dtr-org/unit-e

High-bandwidth compact block does not check stake

AM5800 opened this issue · 0 comments

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