{"record":{"id":"daa7806ecb77d503","repo":"nautechsystems/nautilus_trader","slug":"verified-inclusion-timestamp-exceeds-nanoseconds","errorCode":null,"errorMessage":"Verified inclusion timestamp exceeds nanoseconds","messagePattern":"Verified inclusion timestamp exceeds nanoseconds","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/blockchain/src/execution/client.rs","lineNumber":4689,"sourceCode":"        ts_event,\n        ts_event,\n        false,\n        false,\n    );\n    emitter.try_send_order_event(OrderEventAny::Rejected(rejected))\n}\n\nfn finalized_inclusion_time(included: &IncludedTransaction) -> anyhow::Result<UnixNanos> {\n    let inclusion = &included.finality.inclusion_header;\n    anyhow::ensure!(\n        inclusion.number == included.block_number\n            && inclusion.hash == included.receipt.block_hash.to_string(),\n        \"Verified inclusion header does not match the finalized receipt\"\n    );\n    let timestamp = inclusion.timestamp;\n    let nanos = timestamp\n        .checked_mul(NANOSECONDS_IN_SECOND)\n        .ok_or_else(|| anyhow::anyhow!(\"Verified inclusion timestamp exceeds nanoseconds\"))?;\n    Ok(UnixNanos::from(nanos))\n}\n\nfn execution_event_id(tx_hash: B256, event: &[u8]) -> UUID4 {\n    let mut identity = Vec::with_capacity(tx_hash.len() + event.len());\n    identity.extend_from_slice(tx_hash.as_slice());\n    identity.extend_from_slice(event);\n    let digest = keccak256(identity);\n    let mut bytes = [0u8; 16];\n    bytes.copy_from_slice(&digest[..16]);\n    UUID4::from_bytes(bytes)\n}\n\nstruct FinalizedSwapFill {\n    venue_order_id: VenueOrderId,\n    trade_id: TradeId,\n    last_qty: Quantity,\n    last_px: Price,","sourceCodeStart":4671,"sourceCodeEnd":4707,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/blockchain/src/execution/client.rs#L4671-L4707","documentation":"This library verifies a blockchain transaction inclusion by converting the inclusion block's timestamp (in seconds) into nanoseconds for the UnixNanos domain type. The checked_mul against NANOSECONDS_IN_SECOND fails when the seconds value would overflow the i64 nanoseconds range, so the library aborts rather than producing a corrupted timestamp.","triggerScenarios":"Calling the finalized-swap verification flow when inclusion.timestamp is an absurdly large value (e.g. corrupted RPC response, timestamp in milliseconds instead of seconds, or u64 max sentinel from a malicious/faulty node) so that timestamp * 1e9 exceeds the integer range.","commonSituations":"A misconfigured or buggy RPC provider returning timestamps already in milliseconds or nanoseconds; a mocked/fixture header with a placeholder timestamp; integer width differences after a dependency upgrade changing UnixNanos storage.","solutions":["Verify the RPC node returns block.timestamp in seconds (hex-decoded) and not milliseconds; if in ms, divide by 1000 before this call","Re-fetch the inclusion header from a trusted endpoint; a poisoned timestamp usually indicates a bad upstream response","Check that NANOSECONDS_IN_SECOND and the arithmetic type width match the UnixNanos::from contract for your platform","Clamp or validate timestamp <= i64::MAX / 1_000_000_000 before calling the verification API"],"exampleFix":"// before\nlet nanos = timestamp.checked_mul(NANOSECONDS_IN_SECOND)?;\n// after\nlet timestamp_secs = if timestamp > 1_000_000_000_000 { timestamp / 1000 } else { timestamp };\nlet nanos = timestamp_secs.checked_mul(NANOSECONDS_IN_SECOND)?;","handlingStrategy":"validation","validationCode":"const MAX_TS_SECS: u64 = (i64::MAX as u64) / 1_000_000_000;\nif inclusion.timestamp > MAX_TS_SECS {\n    return Err(anyhow!(\"timestamp {} too large for nanosecond conversion\", inclusion.timestamp));\n}","typeGuard":"fn ts_in_nanos_range(ts: u64) -> bool { ts <= (i64::MAX as u64) / 1_000_000_000 }","tryCatchPattern":"match timestamp.checked_mul(NANOSECONDS_IN_SECOND) {\n    Some(nanos) => Ok(UnixNanos::from(nanos)),\n    None => { log::error!(\"timestamp overflow: {}\", timestamp); Err(...) }\n}","preventionTips":["Assert header timestamps are in seconds at RPC response boundary","Bound-check timestamps against a sane max (year 2100) before arithmetic","Use checked arithmetic everywhere timestamps are scaled","Pin and review RPC provider behavior on timestamp units"],"tags":["overflow","timestamp","blockchain","integer-arithmetic"],"backgroundTag":"value-out-of-range","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}