[Bug] Malicious validator can send fake BlockResponse to block honest validators from processing messages
elderhammer opened this issue Β· comments
π Bug Report
- Block.Transactions limits the maximum number of transactions to 1048575 in the deserialization logic
https://github.com/AleoNet/snarkVM/blob/454d555a0ee1478dce5fa1822b64525a361b6b27/ledger/block/src/transactions/bytes.rs#L29-L32
// Ensure the number of transactions is within bounds.
if num_txs as usize > Self::MAX_TRANSACTIONS {
return Err(error("Failed to read transactions: too many transactions"));
}
- Malicious validators can construct BlockResponse messages by filling a large number of fake transactions
- The victim's message processing logic is stuck because of the deserialization of a large number of fake transactions
snarkOS/node/bft/src/gateway.rs
Lines 634 to 635 in cf83035
- The victim's block synchronization may stop due to being stuck on deserialization, see: ProvableHQ#6
Your Environment
snarkOS Version: cf83035
I think there are two problems to solve:
- Refer to the changes in #3304 and put the deserialization work into the rayon thread
- Appropriately reduce MAX_TRANSACTIONS (I remember that each certificate can only have a maximum of 50 transactions)
I think #3304 should avoid the node getting stuck on big blocks. That said, there's still a deadlock in sync that we haven't found yet.
I don't know about the MAX_TRANSACTIONS
I think #3304 should avoid the node getting stuck on big blocks. That said, there's still a deadlock in sync that we haven't found yet.
I don't know about the MAX_TRANSACTIONS
I've looked at change 3304, which is a change to node/router/src/inbound.rs, but the problem described there is within the BFT module:
snarkOS/node/bft/src/gateway.rs
Lines 629 to 644 in cf83035
The value of MAX_TRANSACTIONS is hardcoded to 1048575, which means that a fake BlockResponse may be filled with 1048575 transactions, which will make deserialization extremely time-consuming.
it's probably a good idea to defer this deserialization to rayon in Gateway too, yes.
On the MAX_TRANSACTIONS
front, there are 2 limiters:
- The protocol limit allows up to
2^20
transactions according to our merkle tree standard. - The BFT worst case scenario formula is
MAX_NUM_VALIDATORS * NUM_TRANSACTIONS_IN_PROPOSAL * MAX_GC_ROUNDS
as defined byTransactions::<N>::MAX_ABORTED_TRANSACTIONS
. In testnet, this value is 100 * 50 * 100 = 500,000. Which is already large enough that the problem still persists
I would say that this problem needs a more fundamental fix/avoidance than just lowering the size check.