Skip to content

Commit ade80f1

Browse files
committed
store, chain/ethereum: Handle pre-Byzantium receipt status correctly
1 parent 7109530 commit ade80f1

File tree

2 files changed

+10
-12
lines changed

2 files changed

+10
-12
lines changed

chain/ethereum/src/runtime/abi.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use anyhow::anyhow;
66
use async_trait::async_trait;
77
use graph::abi;
88
use graph::prelude::alloy;
9+
use graph::prelude::alloy::consensus::TxReceipt;
910
use graph::prelude::alloy::network::ReceiptResponse;
1011
use graph::prelude::alloy::rpc::types::{Log, TransactionReceipt};
1112
use graph::prelude::alloy::serde::WithOtherFields;
@@ -697,6 +698,10 @@ impl ToAscObj<AscEthereumTransactionReceipt>
697698
.ok_or(HostExportError::Unknown(anyhow!(
698699
"Transaction index is missing"
699700
)))?;
701+
let status = match self.inner.status_or_post_state().as_eip658() {
702+
Some(success) => asc_new(heap, &BigInt::from(success as u64), gas).await?,
703+
None => AscPtr::null(), // Pre-EIP-658 (pre-Byzantium) receipt
704+
};
700705
Ok(AscEthereumTransactionReceipt {
701706
transaction_hash: asc_new(heap, &self.transaction_hash, gas).await?,
702707
transaction_index: asc_new(heap, &BigInt::from(transaction_index), gas).await?,
@@ -707,7 +712,7 @@ impl ToAscObj<AscEthereumTransactionReceipt>
707712
gas_used: asc_new(heap, &BigInt::from(self.gas_used), gas).await?,
708713
contract_address: asc_new_or_null(heap, &self.contract_address, gas).await?,
709714
logs: asc_new(heap, &self.logs(), gas).await?,
710-
status: asc_new(heap, &BigInt::from(self.status() as u64), gas).await?,
715+
status,
711716
root: asc_new_or_null(heap, &self.state_root(), gas).await?,
712717
logs_bloom: asc_new(heap, self.inner.bloom().as_slice(), gas).await?,
713718
})

store/postgres/src/transaction_receipt.rs

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -45,18 +45,11 @@ impl TryFrom<RawTransactionReceipt> for LightTransactionReceipt {
4545
let block_number = block_number.map(u64::from_be_bytes);
4646
let gas_used = gas_used.map(u64::from_be_bytes).unwrap_or(0);
4747

48-
// Handle both old U64 format and new boolean format
48+
// Status is non-zero for success, zero for failure. Works for any byte length.
49+
// Defaults to true for pre-Byzantium receipts (no status field), consistent with alloy.
4950
let status = status
50-
.map(|bytes| {
51-
match bytes.len() {
52-
1 => bytes[0] != 0, // New format: single byte
53-
8 => {
54-
u64::from_be_bytes(drain_vector::<8>(bytes.to_vec()).unwrap_or([0; 8])) != 0
55-
} // Old format: U64
56-
_ => false, // Fallback
57-
}
58-
})
59-
.unwrap_or(false);
51+
.map(|bytes| bytes.iter().any(|&b| b != 0))
52+
.unwrap_or(true);
6053

6154
Ok(LightTransactionReceipt {
6255
transaction_hash: transaction_hash.into(),

0 commit comments

Comments
 (0)