{"record":{"id":"d9ec8ba21e1b1d96","repo":"linera-io/linera-protocol","slug":"proof-too-large-total-bytes-bytes-max-max-pro","errorCode":null,"errorMessage":"proof too large: {total_bytes} bytes (max {MAX_PROOF_BYTES})","messagePattern":"proof too large: (.+?) bytes \\(max (.+?)\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"linera-bridge/src/proof/mod.rs","lineNumber":356,"sourceCode":"const MAX_PROOF_BYTES: usize = 32 * 1024;\n\n/// Verifies that a receipt is included in the receipts trie via MPT proof.\n///\n/// Enforces DoS limits on the proof size before forwarding to the trie verifier.\npub fn verify_receipt_inclusion(\n    receipts_root: B256,\n    tx_index: u64,\n    receipt_rlp: &[u8],\n    proof_nodes: &[Bytes],\n) -> Result<()> {\n    ensure!(\n        proof_nodes.len() <= MAX_PROOF_NODES,\n        \"too many proof nodes: {} (max {})\",\n        proof_nodes.len(),\n        MAX_PROOF_NODES\n    );\n    let total_bytes: usize = proof_nodes.iter().map(|n| n.len()).sum();\n    ensure!(\n        total_bytes <= MAX_PROOF_BYTES,\n        \"proof too large: {total_bytes} bytes (max {MAX_PROOF_BYTES})\",\n    );\n\n    let key = receipt_trie_key(tx_index);\n    alloy_trie::proof::verify_proof(receipts_root, key, Some(receipt_rlp.to_vec()), proof_nodes)\n        .map_err(|e| anyhow!(\"MPT proof verification failed: {e}\"))\n}\n\n/// Decodes a receipt's RLP and extracts its logs.\n///\n/// Handles EIP-2718 typed receipts (type byte prefix < 0x80).\n///\n/// This variant exists because when tests build MPT tries\n/// with multiple receipts (e.g. test_build_receipt_proof_multiple_receipts),\n/// each receipt needs a distinct cumulative_gas_used to produce different\n/// RLP encodings. Without that, all empty-log receipts would be byte-identical,\n/// making the trie degenerate.","sourceCodeStart":338,"sourceCodeEnd":374,"githubUrl":"https://github.com/linera-io/linera-protocol/blob/6c226ddcb332ef55118dc8d0aafbd093d5420899/linera-bridge/src/proof/mod.rs#L338-L374","documentation":"The second DoS guard in verify_receipt_inclusion: it sums the byte length of all proof nodes and requires <= MAX_PROOF_BYTES (32 KiB, ~1.7x the theoretical worst case of ~600 bytes x 32 nodes). Oversized total means bloated or malicious nodes, independent of node count.","triggerScenarios":"A proof with few nodes but each padded to be huge (e.g. 2 nodes of 20 KiB); a malformed node list containing embedded extra data; passing unencoded (raw trie structure serialized wholesale) nodes rather than per-node RLP.","commonSituations":"Relayer bugs that serialize the whole trie instead of the proof path; adversarial submissions probing the bridge's verification limits; upstream library change in node encoding inflating sizes.","solutions":["Rebuild the proof from a trusted source and confirm each node is a single RLP-encoded trie node (<~700 bytes)","Reject and alert on submissions from sources repeatedly hitting the cap","If raising the cap for a high-throughput chain, recompute the bound from node-count x max-node-size, keeping headroom"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Pre-check total size before verification (MAX_PROOF_BYTES = 32 KiB)\nlet total: usize = proof_nodes.iter().map(|n| n.len()).sum();\nif total > 32 * 1024 {\n    return Err(anyhow::anyhow!(\"proof payload {total} B exceeds 32 KiB budget\"));\n}","typeGuard":null,"tryCatchPattern":"match verify_receipt_inclusion(root, idx, rlp, nodes) {\n    Ok(()) => Ok(()),\n    Err(e) if e.to_string().contains(\"proof too large\") => {\n        Err(anyhow::anyhow!(\"oversized proof from peer; rate-limit or ban source\"))\n    }\n    Err(e) => Err(e),\n}","preventionTips":["Build proofs with a library that emits one RLP node per entry, not whole-trie serializations","Enforce message size caps at the network layer before deserializing proof payloads","Keep the byte budget derived from node-count x max-node-size when re-tuning constants"],"tags":["ethereum","merkle-proof","mpt","dos-protection","size-limit","bridge","rust"],"backgroundTag":"proof-too-large","analyzedSha":"6c226ddcb332ef55118dc8d0aafbd093d5420899","analyzedAt":"2026-08-22T22:49:09.787Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}