-
Notifications
You must be signed in to change notification settings - Fork 95
feat(core, sequencer): provide checked actions and transaction #2142
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
Conversation
ethanoroshiba
left a comment
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.
Mostly just suggestions and nits, but all the logic here looks solid and quite tidy to me. Nice work! I do think we should try to followup fairly quickly to take the legacy bits out, and it's also probably a good idea to keep this synced with Mainnet until it gets pushed to validators.
crates/astria-sequencer/src/checked_actions/ics20_withdrawal.rs
Outdated
Show resolved
Hide resolved
SuperFluffy
left a comment
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.
astria-core changes look good to me - not yet approving because there seem to be some inaccuracies in the ABCI error codes that are mentioned in the changelog.
Wanna make sure we have a second look.
SuperFluffy
left a comment
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.
Approving for astria-core. Thank you for amending the changelog. :)
ethanoroshiba
left a comment
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.
Reaffirming approval with a couple comments
| let tx_len = tx_bytes.len(); | ||
| info!(transaction_hash = %tx_hash_base_64, "executing transaction"); | ||
| let tx_len = tx.encoded_bytes().len(); | ||
| info!(tx_id = %tx.id(), "executing transaction"); |
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.
Not directly related to this PR but since we're touching this code, do you think it would be better if this was debug!? Just thinking since we're aiming to support hundreds up to a thousand TPS, the info logs could get messy very quickly.
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 a good point, but I'd probably leave as is for now since as you mentioned, this PR doesn't add a new log line here. We can look to change in the future if/when it becomes a noticeable problem.
| if let Err(outcome) = stateless_checks(tx.clone(), &state, metrics).await { | ||
| return outcome; | ||
| } | ||
| let checked_tx = match CheckedTransaction::new(tx_bytes, &state).await { |
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 guessing this is best put for a followup, but it would be nice if upon a recheck and the transaction still existing in mempool, we took the CheckedTransaction straight from the mempool and re-ran mutable checks, instead of constructing a new one each time.
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.
Well, if the tx were in the mempool, we'd have returned from this function just before here, so we don't actually construct a new one in that case.
We might want to change the behaviour in the future so that check_tx does actually rerun the mutable checks, in which case we'd certainly want to do as you suggest.
| return CheckTxOutcome::FailedChecks(error); | ||
| } | ||
| }; | ||
| metrics.record_check_tx_duration_seconds_check_actions(tx_status_end.elapsed()); |
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.
Nit: the metric and function names seem to be a bit at odds here, since the metric would imply the amount of time that the function takes to complete (as it's called check_tx). Maybe it would be best to rename one or the other?
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.
As discussed offline, this name is probably ok as is - we have a few metrics all with similar prefixes.
| let expanded_block_data = | ||
| ExpandedBlockData::new_from_typed_data(&data, with_extended_commit_info).unwrap(); | ||
|
|
||
| let rollup_data_bytes = sequence_data |
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.
is this a duplicate of rollup_data_bytes defined previously?
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 more or less is. The first one (which I should probably rename for clarity) is an iterator over (&RollupId, &Bytes) while this one is a Vec of (RollupId, Bytes).
I changed this in 9bf25b6 to create the second instance using the first one so it's clear they're essentially the same.
| self.checked_bridge_lock | ||
| .run_mutable_checks(&state) | ||
| .await | ||
| .wrap_err("mutable checks for bridge lock failed for bridge transfer") |
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.
this is invalid, as bridge transfers are intended to only be sent from bridge accounts. change the check here to bail if tx sender is not a bridge account
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 think that's incorrect. self.checked_bridge_lock is an instance of CheckedBridgeLockImpl<false>, and CheckedBridgeLockImpl<false>::run_mutable_checks skips checking for the signer being a bridge account altogether.
The line above (self.checked_bridge_unlock.run_mutable_checks) actually ensures the signer is the authorized bridge account withdrawer, which implicitly ensures the signer is also a bridge account afaik.
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.
ah i missed that this was on CheckedBridgeLockImpl<false>, sorry! however this should still check that the receiver of the transfer is a bridge account as well.
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 think that's covered when we construct the CheckedBridgeTransfer. It's calling CheckedBridgeLockImpl::<false>::new, which calls state.get_bridge_account_ibc_asset(&action.to) which ensures the receiver is a bridge account.
This is deemed an immutable check rather than part of the mutable checks since we're only interested in checks which can mutate from passing to failing. We don't care about the other way round since the CheckedAction will fail to be constructed if the checks fail.
Since there's no way to "unset" or uninitialize a bridge account, then this check that the receiver is a bridge account only needs to be run once, during construction.
crates/astria-sequencer/src/checked_actions/bridge_sudo_change.rs
Outdated
Show resolved
Hide resolved
crates/astria-sequencer/src/checked_actions/ics20_withdrawal.rs
Outdated
Show resolved
Hide resolved
crates/astria-sequencer/src/checked_actions/ics20_withdrawal.rs
Outdated
Show resolved
Hide resolved
crates/astria-sequencer/src/checked_actions/init_bridge_account.rs
Outdated
Show resolved
Hide resolved
crates/astria-sequencer/src/checked_actions/rollup_data_submission.rs
Outdated
Show resolved
Hide resolved
## Summary This updates the sequencer benchmarks to actually run on macOS, and fixes a couple of issues around the mempool benchmarks. ## Background The benchmarks could previously only be run on Linux. Since they're also not being run regularly, they got broken at some point. They were further disabled during the large PR #2142. Since I was working on fixing them anyway, I took the opportunity to improve the initialization of the test data. This has resulted in the total time to execute the full mempool suite dropping from ~6.5 mins to ~1.5 mins and means all tests are now able to complete 100 iterations (several could only manage one iteration previously). ## Changes - Used an item from the `astria-sequencer` crate in the benchmark's `main` function to resolve the issue of the tests not running on macOS. - Fixed an issue where the tests were reusing identical txs, causing initialization to fail with an `InsertionError::AlreadyPresent` error. - Memoized test data to reduce test initialization times. - Refactored `PendingTransactionsForAccount::find_demotables` to use an existing method, deduplicating code. - Refactored tests to use updated test utilities. ## Testing Confirmed the benchmarks ran on macOS locally. The `app` ones take a very long time to run and this should be investigated and fixed. To run only the mempool ones: ``` cargo bench --features=benchmark -qp astria-sequencer mempool ``` ## Changelogs No updates required. ## Related Issues Closes #1355.
## Summary This updates the sequencer benchmarks to actually run on macOS, and fixes a couple of issues around the mempool benchmarks. ## Background The benchmarks could previously only be run on Linux. Since they're also not being run regularly, they got broken at some point. They were further disabled during the large PR #2142. Since I was working on fixing them anyway, I took the opportunity to improve the initialization of the test data. This has resulted in the total time to execute the full mempool suite dropping from ~6.5 mins to ~1.5 mins and means all tests are now able to complete 100 iterations (several could only manage one iteration previously). ## Changes - Used an item from the `astria-sequencer` crate in the benchmark's `main` function to resolve the issue of the tests not running on macOS. - Fixed an issue where the tests were reusing identical txs, causing initialization to fail with an `InsertionError::AlreadyPresent` error. - Memoized test data to reduce test initialization times. - Refactored `PendingTransactionsForAccount::find_demotables` to use an existing method, deduplicating code. - Refactored tests to use updated test utilities. ## Testing Confirmed the benchmarks ran on macOS locally. The `app` ones take a very long time to run and this should be investigated and fixed. To run only the mempool ones: ``` cargo bench --features=benchmark -qp astria-sequencer mempool ``` ## Changelogs No updates required. ## Related Issues Closes #1355.
Summary
This introduces
CheckedAction,CheckedTransactionandChecked...wrappers for each action type.Background
We want to have stricter checks performed when
CheckTxis called on a new tx in order to avoid accepting txs which subsequently fail execution.Checks on txs and their included actions are now split into two categories: mutable and immutable. On construction of a checked object, both types of checks are run. Subsequently, only the mutable checks are re-run, and this is currently only done at the start of executing the action/transaction.
Nonce and balance checks are excluded from these checks as the Mempool only puts forward for execution txs which should have valid nonces and sufficient account balances.
In order to ensure such checks have been performed, the sequencer now deals almost exclusively in checked flavours of actions and txs.
As a result of this, many tests which previously used txs had to be refactored to ensure that constructing the equivalent checked txs would succeed.
Changes
Checked...types for actions andTransaction. Replaced usage throughout sequencer codebase of the unchecked flavours of these.ExpandedBlockData::user_submitted_transactionsto UN-parsed transactions so that all checking can be done when constructing aCheckedTransaction.test_utilsmodule. As well as pre-existing helper functions, there is now aFixturefor intializing a new chain along with several builders/initializers to aid in constructing objects to be used in tests. These are provided with doc comments which should explain how to use them.Testing
tests_execute_transaction.rslargely redundant, hence that file has been deleted. Coverage was also provided forIbcRelaywhere none existed before, but the setup difficulty for testingIcs20Withdrawalis such that only a subset of the code paths are tested (as is the case currently).CheckedTransactionalso has extensive unit test coverage for construction and execution, and covers any deleted tests fromtests_execute_transaction.rsnot already catered for by the action unit tests.Changelogs
Changelogs updated.
Metrics
ASTRIA_SEQUENCER_CHECK_TX_FAILED_ACTION_CHECKSASTRIA_SEQUENCER_CHECK_TX_DURATION_SECONDS_CHECK_ACTIONSASTRIA_SEQUENCER_CHECK_TX_DURATION_SECONDS_RECHECKASTRIA_SEQUENCER_CHECK_TX_REMOVED_TOO_LARGEtoASTRIA_SEQUENCER_CHECK_TX_FAILED_TX_TOO_LARGEASTRIA_SEQUENCER_CHECK_TX_REMOVED_FAILED_STATELESSASTRIA_SEQUENCER_CHECK_TX_DURATION_SECONDS_PARSE_TXASTRIA_SEQUENCER_CHECK_TX_DURATION_SECONDS_CHECK_STATELESSASTRIA_SEQUENCER_CHECK_TX_DURATION_SECONDS_CHECK_TRACKEDASTRIA_SEQUENCER_CHECK_TX_DURATION_SECONDS_CHECK_CHAIN_IDASTRIA_SEQUENCER_CHECK_TX_DURATION_SECONDS_CHECK_REMOVEDASTRIA_SEQUENCER_CHECK_TX_DURATION_SECONDS_CONVERT_ADDRESSBreaking Changelist
Related Issues
Closes #1958.
Closes #1620.