-
Notifications
You must be signed in to change notification settings - Fork 987
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Prevent handling triggers for failed transactions #2511
Conversation
4d43c22
to
91f10a0
Compare
3ca48da
to
2659d6a
Compare
a18a0dc
to
c3922f1
Compare
chain_store | ||
.transaction_statuses_in_block_range(&(from..to)) | ||
.expect("failed to fetch failed transactions in the database") | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can do an early return with a once
stream that emits an error https://docs.rs/futures/0.1.31/futures/stream/fn.once.html.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alternatively, we can log the error and move on as if we had nothing cached.
store/postgres/src/chain_store.rs
Outdated
for receipt in receipts.into_iter() { | ||
match (receipt.status, receipt.gas_used) { | ||
(Some(_status), _) => { | ||
statuses.insert(receipt.transaction_hash, receipt.is_sucessful()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could replace is_successful()
with just !status.is_zero()
store/postgres/src/chain_store.rs
Outdated
let mut statuses = HashMap::new(); | ||
let mut pending = HashMap::new(); | ||
for receipt in receipts.into_iter() { | ||
match (receipt.status, receipt.gas_used) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If gas_used
is None
this should return an error.
2eede27
to
b89879f
Compare
90b6b03
to
9423de1
Compare
Ok(Some(receipt)) => Ok(receipt), | ||
Ok(None) => bail!("Could not find transaction receipt"), | ||
Err(error) => bail!("Failed to fetch transaction receipt: {}", error), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm considering the absence of a receipt to be an error here.
// Filter call triggers from unsuccessful transactions | ||
block.trigger_data.retain(|trigger| { | ||
if let EthereumTrigger::Call(call_trigger) = trigger { | ||
// Unwrap: We already checked that those values exist | ||
transaction_success[&call_trigger.transaction_hash.unwrap()] | ||
} else { | ||
// We are not filtering other types of triggers | ||
true | ||
} | ||
}); | ||
Ok(block) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's important to note that a block with empty triggers might be returned from this.
I'm not sure if I should drop the whole block in those cases.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Returning an empty block is fine.
let query = TransactionReceiptQuery { | ||
schema_name: chain_name, | ||
block_hash: block_hash.as_bytes(), | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm still not sure if chain_name
maps strictly to schema_name
I'll have that checked.
14ec576
to
8a51b80
Compare
1030854
to
91fdcaa
Compare
// Filter call triggers from unsuccessful transactions | ||
block.trigger_data.retain(|trigger| { | ||
if let EthereumTrigger::Call(call_trigger) = trigger { | ||
// Unwrap: We already checked that those values exist | ||
transaction_success[&call_trigger.transaction_hash.unwrap()] | ||
} else { | ||
// We are not filtering other types of triggers | ||
true | ||
} | ||
}); | ||
Ok(block) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Returning an empty block is fine.
cbbad79
to
660d419
Compare
Please don't merge yet. |
fa8c2e4
to
fb6b8fd
Compare
@@ -656,7 +656,7 @@ impl UnresolvedMapping { | |||
pub struct UnifiedMappingApiVersion(Option<Version>); | |||
|
|||
impl UnifiedMappingApiVersion { | |||
pub fn equal_or_greater_than(&self, other_version: &'static Version) -> bool { | |||
pub fn equal_or_greater_than(&self, other_version: &Version) -> bool { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the 'static
here doesn't work anymore?
Resolves #2409
This PR adds a verification step to call-handler execution that filters off traces with failed transactions.
For non-final blocks, we determine failure by inspecting each transaction receipt and gas usage, which are already present in program memory, so it should be fast.
For final blocks, we search the database once for each block. If that data is absent, we call an external API once for each transaction receipt.