linera-io/linera-protocol · error

expected 224 bytes of event data (7 x 32), got {}

Error message

expected 224 bytes of event data (7 x 32), got {}

What it means

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.

Source

Thrown at linera-bridge/src/proof/mod.rs:440

/// The `depositor` field is indexed (stored in `topics[1]`); all other parameters are
/// non-indexed and encoded in the log data.
pub fn parse_deposit_event(log: &ReceiptLog, expected_emitter: Address) -> Result<DepositEvent> {
    ensure!(
        log.address == expected_emitter,
        "log emitter {:?} does not match expected bridge contract {:?}",
        log.address,
        expected_emitter
    );
    ensure!(
        log.topics.first() == Some(&deposit_event_signature()),
        "event topic does not match DepositInitiated signature"
    );
    ensure!(
        log.topics.len() == 2,
        "expected exactly 2 topics (signature + indexed depositor), got {}",
        log.topics.len()
    );
    ensure!(
        log.data.len() == 224,
        "expected 224 bytes of event data (7 x 32), got {}",
        log.data.len()
    );

    // Indexed `depositor` is in topics[1], left-padded to 32 bytes.
    let depositor_topic = log.topics[1];
    ensure!(
        depositor_topic.as_slice()[..12] == [0u8; 12],
        "invalid ABI encoding: depositor topic padding bytes (0..12) must be zero"
    );
    let depositor = Address::from_slice(&depositor_topic.as_slice()[12..32]);

    let d = &log.data;

    // ABI encodes addresses as left-padded 32-byte words; the first 12 bytes must be zero.
    ensure!(
        d[128..140] == [0u8; 12],

View on GitHub (pinned to 6c226ddcb3)

Solutions

  1. Dump log.data.len() for the failing log and divide by 32 to see how many words the contract actually emitted.
  2. 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.
  3. 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.
  4. Regenerate test fixtures (build_deposit_event_data) from the new ABI so tests encode the same shape the parser accepts.

Example fix

// before
ensure!(log.data.len() == 224, "expected 224 bytes of event data (7 x 32), got {}", log.data.len());

// after (ABI now carries 8 non-indexed words)
ensure!(log.data.len() == 256, "expected 256 bytes of event data (8 x 32), got {}", log.data.len());
// ...and extend the field extraction below to cover d[224..256]
Defensive patterns

Strategy: validation

Validate before calling

fn has_deposit_data_shape(log: &ReceiptLog) -> bool {
    log.topics.first() == Some(&deposit_event_signature())
        && log.topics.len() == 2
        && log.data.len() == 224 // 7 x 32-byte ABI words
}

if !has_deposit_data_shape(&log) {
    tracing::warn!(len = log.data.len(), "skipping DepositInitiated-shaped log with wrong data size");
    continue;
}
let event = parse_deposit_event(&log, bridge_addr)?;

Try / catch

match parse_deposit_event(&log, bridge_addr) {
    Ok(ev) => Some(ev),
    Err(e) if e.to_string().contains("expected 224 bytes") => {
        tracing::warn!(data_len = log.data.len(), "ABI drift suspected; skipping log");
        None
    }
    Err(e) => { tracing::error!(error = %e, "deposit parse failed"); None }
}

Prevention

When it happens

Trigger: 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).

Common situations: 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.

Related errors


AI-assisted analysis of linera-io/linera-protocol@6c226ddcb3 (2026-08-22). Data as JSON: /api/errors/55abf3312f2d7b59. Report an issue: GitHub.