Skip to content

Commit cbbad79

Browse files
committed
chain, graph: Add evaluate_transaction_status function
1 parent 74d3f3d commit cbbad79

File tree

4 files changed

+24
-41
lines changed

4 files changed

+24
-41
lines changed

chain/ethereum/src/ethereum_adapter.rs

+1-21
Original file line numberDiff line numberDiff line change
@@ -1752,7 +1752,7 @@ async fn filter_call_triggers_from_unsuccessful_transactions(
17521752
for (transaction, receipt) in receipts_and_transactions.into_iter() {
17531753
transaction_success.insert(
17541754
&transaction.hash,
1755-
is_transaction_successful(&transaction, &receipt)?,
1755+
evaluate_transaction_status(receipt.status, receipt.gas_used, &transaction.gas)?,
17561756
);
17571757
}
17581758

@@ -1776,23 +1776,3 @@ async fn filter_call_triggers_from_unsuccessful_transactions(
17761776
});
17771777
Ok(block)
17781778
}
1779-
1780-
/// Evaluates if a given transaction was successful.
1781-
///
1782-
/// According to EIP-658, there are two ways of checking if a transaction failed:
1783-
/// 1. by checking if it ran out of gas.
1784-
/// 2. by looking at its receipt "status" boolean field, which may be absent for blocks before
1785-
/// Byzantium fork.
1786-
fn is_transaction_successful(
1787-
transaction: &Transaction,
1788-
receipt: &LightTransactionReceipt,
1789-
) -> anyhow::Result<bool> {
1790-
if let Some(status) = receipt.is_sucessful() {
1791-
Ok(status)
1792-
} else {
1793-
let gas_used = receipt
1794-
.gas_used
1795-
.ok_or(anyhow::anyhow!("Running in light client mode"))?;
1796-
Ok(gas_used >= transaction.gas)
1797-
}
1798-
}

graph/src/components/ethereum/mod.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ use web3::types::H256;
55

66
pub use self::network::NodeCapabilities;
77
pub use self::types::{
8-
EthereumBlock, EthereumBlockWithCalls, EthereumCall, LightEthereumBlock, LightEthereumBlockExt,
8+
evaluate_transaction_status, EthereumBlock, EthereumBlockWithCalls, EthereumCall,
9+
LightEthereumBlock, LightEthereumBlockExt,
910
};
1011

1112
#[derive(Clone, Debug, PartialEq, Eq, Hash)]

graph/src/components/ethereum/types.rs

+21-9
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use serde::{Deserialize, Serialize};
22
use std::{convert::TryFrom, sync::Arc};
33
use web3::types::{
44
Action, Address, Block, Bytes, Log, Res, Trace, Transaction, TransactionReceipt, H256, U256,
5+
U64,
56
};
67

78
use crate::{
@@ -91,15 +92,26 @@ impl EthereumBlockWithCalls {
9192
"failed to find the transaction for this call"
9293
))?;
9394

94-
// assume the transaction failed if all gas was used
95-
if receipt
96-
.gas_used
97-
.ok_or(anyhow::anyhow!("Running in light client mode)"))?
98-
>= transaction.gas
99-
{
100-
return Ok(false);
101-
}
102-
Ok(matches!(receipt.status, Some(x) if x == web3::types::U64::from(1)))
95+
evaluate_transaction_status(receipt.status, receipt.gas_used, &transaction.gas)
96+
}
97+
}
98+
99+
/// Evaluates if a given transaction was successful.
100+
///
101+
/// According to EIP-658, there are two ways of checking if a transaction failed:
102+
/// 1. by checking if it ran out of gas.
103+
/// 2. by looking at its receipt "status" boolean field, which may be absent for blocks before
104+
/// Byzantium fork.
105+
pub fn evaluate_transaction_status(
106+
receipt_status: Option<U64>,
107+
receipt_gas_used: Option<U256>,
108+
transaction_gas: &U256,
109+
) -> anyhow::Result<bool> {
110+
if receipt_gas_used.ok_or(anyhow::anyhow!("Running in light client mode)"))? >= *transaction_gas
111+
{
112+
Ok(false)
113+
} else {
114+
Ok(matches!(receipt_status, Some(status) if !status.is_zero()))
103115
}
104116
}
105117

graph/src/components/transaction_receipt.rs

-10
Original file line numberDiff line numberDiff line change
@@ -110,16 +110,6 @@ pub struct LightTransactionReceipt {
110110
pub status: Option<U64>,
111111
}
112112

113-
impl LightTransactionReceipt {
114-
/// `0x0` indicates transaction failure, `0x1` indicates transaction success.
115-
/// Set for blocks mined after Byzantium hard fork, `None` before.
116-
///
117-
/// Relevant EIPs: 609, 658
118-
pub fn is_sucessful(&self) -> Option<bool> {
119-
self.status.map(|status| !status.is_zero())
120-
}
121-
}
122-
123113
/// Converts Vec<u8> to [u8; N], where N is the vector's expected lenght.
124114
/// Fails if input size is larger than output size.
125115
pub(crate) fn drain_vector<const N: usize>(input: Vec<u8>) -> Result<[u8; N], anyhow::Error> {

0 commit comments

Comments
 (0)