dtr-org / unit-e

A digital currency for a new era of decentralized trust
https://unit-e.io
MIT License
45 stars 15 forks source link

High-bandwidth compact block does not check stake #903

Closed AM5800 closed 5 years ago

AM5800 commented 5 years ago

Describe the bug In high-bandwidth mode compact blocks are sent before full validation is performed. This sometimes can lead to invalid blocks flooding the network (because no node fully checks blocks before sending). However in PoW setting this is not a very big problem - because PoW is checked and attacker can not create many such blocks.

We inherited this code from bitcoin so we send compact blocks right after block header was checked. And this is not enough in PoS setting.

This issue not only allows an attacker to degrade network performance by forcing it to relay invalid blocks, but also allows disk exhaustion attack - because all nodes are saving such blocks on disk

To Reproduce Consider this functional test excerpt:

#fully connect nodes for convenience (8 total nodes in experiment)
for src in self.nodes:
    for dst in range(src.index + 1, len(self.nodes)):
        connect_nodes(src, dst)

node0.generate(1)  # To generate some outputs
spent = node0.listunspent(1)[0]
spend_utxo(spent, node0)
node0.generate(5)

#create block extending tip, but use already spent utxo as a stake
block = create_block_on_tip(node0, spent) #second param is stake
self.sync_all()

p2p.send_and_ping(msg_block(block))

This resulted in ALL nodes receiving this invalid block, saving it on disk and relaying further.

Key lines from log:

received block 7aa8a1de994a906b489093f082246b541b4fe0a8e08349154e0f5d25bebccbba peer=0 

PeerLogicValidation::NewPoWValidBlock sending header-and-ids 7aa8a1de994a906b489093f082246b541b4fe0a8e08349154e0f5d25bebccbba to peer=1 
sending cmpctblock (409 bytes) peer=1 
PeerLogicValidation::NewPoWValidBlock sending header-and-ids 7aa8a1de994a906b489093f082246b541b4fe0a8e08349154e0f5d25bebccbba to peer=2 
sending cmpctblock (409 bytes) peer=2 
PeerLogicValidation::NewPoWValidBlock sending header-and-ids 7aa8a1de994a906b489093f082246b541b4fe0a8e08349154e0f5d25bebccbba to peer=3 
sending cmpctblock (409 bytes) peer=3

Saving block to disk 7aa8a1de994a906b489093f082246b541b4fe0a8e08349154e0f5d25bebccbba 

ERROR: ConnectBlock: Consensus::CheckTxInputs: 48dd23adb67fe895ec31f80eead4ff77ae1d9c9019e6d1446d5490268cdb69ce, bad-txns-inputs-missingorspent, CheckTxInputs: inputs missing/spent (code 16)

Expected behavior Nodes should not relay invalid blocks that are easy to construct.

Additional context Related #276