{"record":{"id":"55abf3312f2d7b59","repo":"linera-io/linera-protocol","slug":"expected-224-bytes-of-event-data-7-x-32-got","errorCode":null,"errorMessage":"expected 224 bytes of event data (7 x 32), got {}","messagePattern":"expected 224 bytes of event data \\(7 x 32\\), got (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"linera-bridge/src/proof/mod.rs","lineNumber":440,"sourceCode":"/// The `depositor` field is indexed (stored in `topics[1]`); all other parameters are\n/// non-indexed and encoded in the log data.\npub fn parse_deposit_event(log: &ReceiptLog, expected_emitter: Address) -> Result<DepositEvent> {\n    ensure!(\n        log.address == expected_emitter,\n        \"log emitter {:?} does not match expected bridge contract {:?}\",\n        log.address,\n        expected_emitter\n    );\n    ensure!(\n        log.topics.first() == Some(&deposit_event_signature()),\n        \"event topic does not match DepositInitiated signature\"\n    );\n    ensure!(\n        log.topics.len() == 2,\n        \"expected exactly 2 topics (signature + indexed depositor), got {}\",\n        log.topics.len()\n    );\n    ensure!(\n        log.data.len() == 224,\n        \"expected 224 bytes of event data (7 x 32), got {}\",\n        log.data.len()\n    );\n\n    // Indexed `depositor` is in topics[1], left-padded to 32 bytes.\n    let depositor_topic = log.topics[1];\n    ensure!(\n        depositor_topic.as_slice()[..12] == [0u8; 12],\n        \"invalid ABI encoding: depositor topic padding bytes (0..12) must be zero\"\n    );\n    let depositor = Address::from_slice(&depositor_topic.as_slice()[12..32]);\n\n    let d = &log.data;\n\n    // ABI encodes addresses as left-padded 32-byte words; the first 12 bytes must be zero.\n    ensure!(\n        d[128..140] == [0u8; 12],","sourceCodeStart":422,"sourceCodeEnd":458,"githubUrl":"https://github.com/linera-io/linera-protocol/blob/6c226ddcb332ef55118dc8d0aafbd093d5420899/linera-bridge/src/proof/mod.rs#L422-L458","documentation":"parse_deposit_event expects log.data to be exactly 224 bytes: seven ABI-encoded 32-byte words (source_chain_id, target_chain_id, target_application_id, target_account_owner, token, amount, nonce). The ensure at linera-bridge/src/proof/mod.rs:440 fails when the data section length differs, which means the non-indexed parameter list of the emitted event does not match the 7-field layout the parser was built for. Because topic[0] already matched, this is an event-shape mismatch, not a routing problem.","triggerScenarios":"A DepositInitiated event with an added or removed non-indexed parameter (e.g., a metadata string or extra fee field) so data is no longer 7*32 bytes; a test fixture that packs the wrong number of words via build_deposit_event_data; a contract upgrade that switched a field to indexed (shrinking data to 6 words while growing topics).","commonSituations":"Contract redeployed with a richer event but scanner still runs old parser; test helpers and parser drift out of sync after an ABI edit; decoding an analogous event (e.g., WithdrawalInitiated) that shares topic[0] by coincidence of signature hashing; chain with non-standard receipt encoding feeding evm_scan_iteration.","solutions":["Dump log.data.len() for the failing log and divide by 32 to see how many words the contract actually emitted.","Diff the contract's current ABI against the 7 fields the parser decodes at d[0..224]; update the offsets and the 224 constant together if the ABI legitimately changed.","Check whether a field was moved between indexed (topics) and non-indexed (data): if so, error 180 fires too — fix both sides in one change.","Regenerate test fixtures (build_deposit_event_data) from the new ABI so tests encode the same shape the parser accepts."],"exampleFix":"// before\nensure!(log.data.len() == 224, \"expected 224 bytes of event data (7 x 32), got {}\", log.data.len());\n\n// after (ABI now carries 8 non-indexed words)\nensure!(log.data.len() == 256, \"expected 256 bytes of event data (8 x 32), got {}\", log.data.len());\n// ...and extend the field extraction below to cover d[224..256]","handlingStrategy":"validation","validationCode":"fn has_deposit_data_shape(log: &ReceiptLog) -> bool {\n    log.topics.first() == Some(&deposit_event_signature())\n        && log.topics.len() == 2\n        && log.data.len() == 224 // 7 x 32-byte ABI words\n}\n\nif !has_deposit_data_shape(&log) {\n    tracing::warn!(len = log.data.len(), \"skipping DepositInitiated-shaped log with wrong data size\");\n    continue;\n}\nlet event = parse_deposit_event(&log, bridge_addr)?;","typeGuard":null,"tryCatchPattern":"match parse_deposit_event(&log, bridge_addr) {\n    Ok(ev) => Some(ev),\n    Err(e) if e.to_string().contains(\"expected 224 bytes\") => {\n        tracing::warn!(data_len = log.data.len(), \"ABI drift suspected; skipping log\");\n        None\n    }\n    Err(e) => { tracing::error!(error = %e, \"deposit parse failed\"); None }\n}","preventionTips":["Add an ABI-compatibility assertion (expected data length constant) shared by tests and parser.","Failing this check right after a contract upgrade means the parser is stale: update offsets in the same commit as the ABI change.","Log the observed length to classify one-word-added vs field-moved changes quickly.","Never widen the check silently; a wrong-size decode means wrong offsets and corrupted deposits."],"tags":["ethereum","evm","abi","event-logs","rust","linera-bridge"],"backgroundTag":"evm-event-abi-mismatch","analyzedSha":"6c226ddcb332ef55118dc8d0aafbd093d5420899","analyzedAt":"2026-08-22T22:49:09.787Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}