Skip to content
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

Merged
merged 1 commit into from
Jul 19, 2021

Conversation

tilacog
Copy link
Contributor

@tilacog tilacog commented Jun 1, 2021

Resolves #2409

  • Handle Non-Final blocks
  • Handle Final blocks
    • Fetch existing transaction receipts from database
    • Fetch existing transaction receipts from ethereum client
  • Add stopwatch metrics
  • Add manifest version switch

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.

@tilacog tilacog requested a review from leoyvens June 1, 2021 17:56
@tilacog tilacog force-pushed the tiago/dont-handle-failed-transactions branch from 4d43c22 to 91f10a0 Compare June 2, 2021 14:17
@tilacog tilacog force-pushed the tiago/dont-handle-failed-transactions branch from 3ca48da to 2659d6a Compare June 4, 2021 19:12
@tilacog tilacog force-pushed the tiago/dont-handle-failed-transactions branch 8 times, most recently from a18a0dc to c3922f1 Compare June 16, 2021 18:00
chain_store
.transaction_statuses_in_block_range(&(from..to))
.expect("failed to fetch failed transactions in the database")
};
Copy link
Collaborator

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.

Copy link
Collaborator

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.

for receipt in receipts.into_iter() {
match (receipt.status, receipt.gas_used) {
(Some(_status), _) => {
statuses.insert(receipt.transaction_hash, receipt.is_sucessful());
Copy link
Collaborator

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()

let mut statuses = HashMap::new();
let mut pending = HashMap::new();
for receipt in receipts.into_iter() {
match (receipt.status, receipt.gas_used) {
Copy link
Collaborator

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.

@tilacog tilacog force-pushed the tiago/dont-handle-failed-transactions branch 2 times, most recently from 2eede27 to b89879f Compare July 5, 2021 22:36
chain/ethereum/src/adapter.rs Outdated Show resolved Hide resolved
chain/ethereum/src/chain.rs Outdated Show resolved Hide resolved
@tilacog tilacog force-pushed the tiago/dont-handle-failed-transactions branch from 90b6b03 to 9423de1 Compare July 6, 2021 20:49
Comment on lines +1667 to +1673
Ok(Some(receipt)) => Ok(receipt),
Ok(None) => bail!("Could not find transaction receipt"),
Err(error) => bail!("Failed to fetch transaction receipt: {}", error),
Copy link
Contributor Author

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.

Comment on lines 1769 to 1810
// 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)
Copy link
Contributor Author

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.

Copy link
Collaborator

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.

Comment on lines 178 to 171
let query = TransactionReceiptQuery {
schema_name: chain_name,
block_hash: block_hash.as_bytes(),
};
Copy link
Contributor Author

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.

@tilacog tilacog force-pushed the tiago/dont-handle-failed-transactions branch from 14ec576 to 8a51b80 Compare July 6, 2021 21:55
@tilacog tilacog force-pushed the tiago/dont-handle-failed-transactions branch 2 times, most recently from 1030854 to 91fdcaa Compare July 6, 2021 22:21
@tilacog tilacog marked this pull request as ready for review July 7, 2021 17:58
chain/ethereum/Cargo.toml Outdated Show resolved Hide resolved
chain/ethereum/src/chain.rs Outdated Show resolved Hide resolved
chain/ethereum/src/ethereum_adapter.rs Outdated Show resolved Hide resolved
chain/ethereum/src/ethereum_adapter.rs Show resolved Hide resolved
Comment on lines 1769 to 1810
// 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)
Copy link
Collaborator

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.

graph/src/components/ethereum/types.rs Outdated Show resolved Hide resolved
@tilacog tilacog force-pushed the tiago/dont-handle-failed-transactions branch 4 times, most recently from cbbad79 to 660d419 Compare July 9, 2021 22:06
@tilacog tilacog requested a review from leoyvens July 9, 2021 22:29
@tilacog
Copy link
Contributor Author

tilacog commented Jul 9, 2021

Please don't merge yet.
I've to check this w/ a live subgraph first.

@tilacog tilacog force-pushed the tiago/dont-handle-failed-transactions branch 2 times, most recently from fa8c2e4 to fb6b8fd Compare July 15, 2021 19:12
@@ -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 {
Copy link
Collaborator

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?

@tilacog tilacog merged commit e37fec8 into master Jul 19, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Out of gas tx triggers subgraph call handler
2 participants