linera-io/linera-protocol · error · ProofError

no DepositInitiated event found in receipt for tx {tx_hash}

Error message

no DepositInitiated event found in receipt for tx {tx_hash}

What it means

After decoding the canonical receipt, no log has a first topic matching the DepositInitiated event signature. Classified ProofError::Permanent. The proof generator only works for transactions that actually emitted a bridge deposit event, so this transaction is not a provable deposit.

Source

Thrown at linera-bridge/src/proof/gen.rs:188

        let (receipts_root, proof_nodes) =
            crate::proof::build_receipt_proof(&canonical_receipts, tx_index);

        // Sanity check: computed receipts root matches block header
        if receipts_root != block.header.inner.receipts_root {
            return Err(ProofError::Permanent(anyhow::anyhow!(
                "receipts root mismatch: computed {receipts_root}, \
                 header says {}. Receipt encoding may be incorrect.",
                block.header.inner.receipts_root
            )));
        }

        // Find all DepositInitiated log indices from the canonical receipt
        let logs =
            crate::proof::decode_receipt_logs(&receipt_rlp).map_err(ProofError::Permanent)?;
        let log_indices = crate::proof::find_deposit_log_indices(&logs);
        if log_indices.is_empty() {
            return Err(ProofError::Permanent(anyhow::anyhow!(
                "no DepositInitiated event found in receipt for tx {tx_hash}"
            )));
        }

        Ok(DepositProof {
            block_header_rlp,
            receipt_rlp,
            proof_nodes,
            tx_index,
            log_indices,
        })
    }
}

#[cfg(test)]
mod tests {
    #![allow(clippy::cast_possible_truncation)]

View on GitHub (pinned to 6c226ddcb3)

Solutions

  1. Open the transaction on an explorer and confirm it emits a DepositInitiated event from the bridge contract
  2. Use the hash of the actual deposit transaction, not the approval or another tx in the same block
  3. Verify the bridge contract address deployed on this network matches what the proof client targets
  4. If the event shape changed, update the expected signature in the proof code
Defensive patterns

Strategy: try-catch

Validate before calling

// Preflight: confirm the receipt contains a DepositInitiated log before proving.
let receipt = provider.get_transaction_receipt(tx_hash).await?.expect("mined");
let has_deposit = receipt.inner.logs().iter().any(|l| {
    l.topics().first().map(|t| *t == deposit_event_signature()).unwrap_or(false)
});

Try / catch

Err(ProofError::Permanent(e)) if e.to_string().contains("no DepositInitiated event") => {
    // wrong tx: mark this tx_hash as not-a-deposit and drop it from the queue permanently
}

Prevention

When it happens

Trigger: Calling generate_deposit_proof with a transaction hash that is unrelated to the bridge; a deposit sent to a different bridge contract deployment; the receipt's logs empty (plain ETH transfer or failed tx); event signature drift between the deployed contract and this crate's expected signature.

Common situations: Copy-pasting the wrong tx hash from an explorer; multiple bridge deployments (testnet vs mainnet) confused; contract upgrade changing the event; user initiated the deposit but it reverted without logs.

Related errors


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