feat(sequencer)!: enforce block ordering by transaction group #1618
feat(sequencer)!: enforce block ordering by transaction group #1618lobstergrindset merged 16 commits intomainfrom
Conversation
|
Oops, hit the wrong button. This isn't ready for review. |
| BundleableGeneral, | ||
| UnbundleableGeneral, | ||
| BundleableSudo, | ||
| #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] |
There was a problem hiding this comment.
Since this is public now, might be nice to add a little rustdoc comments to the enum and its variants.
| UnbundleableSudo, | ||
| BundleableSudo, | ||
| UnbundleableGeneral, | ||
| BundleableGeneral, |
There was a problem hiding this comment.
Seems like the ordering here is very load-bearing. It might be worth adding explicit values to each variant to make this more obvious (maybe also a non-rustdoc "// NOTE: ..." comment on the enum)?
| UnbundleableSudo, | |
| BundleableSudo, | |
| UnbundleableGeneral, | |
| BundleableGeneral, | |
| UnbundleableSudo = 1, | |
| BundleableSudo = 2, | |
| UnbundleableGeneral = 3, | |
| BundleableGeneral = 4, |
Also probably worth adding a unit test to try and avoid an accidental change here, e.g.
#[test]
fn should_be_in_correct_order() {
assert_eq!(ActionGroup::UnbundleableSudo < ActionGroup::BundleableSudo);
assert_eq!(ActionGroup::BundleableSudo < ActionGroup::UnbundleableGeneral);
assert_eq!(ActionGroup::UnbundleableGeneral < ActionGroup::BundleableGeneral);
}| ); | ||
| excluded_tx_count = excluded_tx_count.saturating_add(1); | ||
| continue; | ||
| return Err(eyre!("max block sequenced data limit passed")); |
There was a problem hiding this comment.
| return Err(eyre!("max block sequenced data limit passed")); | |
| bail!("max block sequenced data limit passed"); |
There was a problem hiding this comment.
Also would be nice to have a unit test for this change, asserting we return here rather than relying on the final tx count causing the proposal to fail. Could be a follow-up PR though, since there are maybe a bunch of similar tests which could be added?
There was a problem hiding this comment.
Added the unit tests checking for the other error cases!
| "transaction error: failed to execute transaction" | ||
| ); | ||
| excluded_tx_count = excluded_tx_count.saturating_add(1); | ||
| return Err(eyre!("transaction failed to execute")); |
There was a problem hiding this comment.
| return Err(eyre!("transaction failed to execute")); | |
| bail!("transaction failed to execute"); |
|
|
||
| assert!(bundleable_sudo >= bundleable_sudo); | ||
| assert!(bundleable_sudo >= unbundleable_sudo); | ||
|
|
There was a problem hiding this comment.
| assert!(unbundleable_sudo >= unbundleable_sudo); | |
SuperFluffy
left a comment
There was a problem hiding this comment.
Looks fine to me, going to follow @Fraser999's approval.
I just left some minor comments.
| /// # Panics | ||
| /// Method is expected to never panic because only `SequenceActions` are added to the bundle, | ||
| /// which should produce a valid variant of the `ActionGroup` type. | ||
| /// which should produce a valid variant of the `Action::Group` type. |
There was a problem hiding this comment.
| /// which should produce a valid variant of the `Action::Group` type. | |
| /// which should produce a valid variant of the [`action::Group`] type. |
| "method is expected to never panic because only `SequenceActions` are added to \ | ||
| the bundle, which should produce a valid variant of the `ActionGroup` type; this \ | ||
| is checked by `tests::transaction_construction_should_not_panic", | ||
| the bundle, which should produce a valid variant of the `Action::Group` type; \ |
There was a problem hiding this comment.
| the bundle, which should produce a valid variant of the `Action::Group` type; \ | |
| the bundle, which should produce a valid variant of the `action::Group` type; \ |
| /// | ||
| /// # Errors | ||
| /// Returns an error if the actions do not make a valid `ActionGroup`. | ||
| /// Returns an error if the actions do not make a valid `Action::Group`. |
There was a problem hiding this comment.
| /// Returns an error if the actions do not make a valid `Action::Group`. | |
| /// Returns an error if the actions do not make a valid [`action::Group`]. |
| group: Group, | ||
| } | ||
|
|
||
| impl PartialEq for TransactionPriority { |
There was a problem hiding this comment.
Isn't this the same as deriving PartialEq?
There was a problem hiding this comment.
Can you say more about what you mean by this? I'm a little confused
There was a problem hiding this comment.
I meant that your manual implementation looks the same as deriving PartialEq. Maybe at some point the type contained some field that you wanted to exclude from the comparison, but then you removed it at some point?
I'd derive PartialEq now instead of doing it manually.
* main: feat(sequencer)!: enforce block ordering by transaction group (#1618) fix(cli): ensure checkTx passes before waiting for inclusion (#1636) chore(sequencer)!: update storage keys locations and values (ENG-898) (#1616) chore: cargo audit warning (#1644) chore(proto, core)!: remove action suffix from all action types (#1630) feat(sequencer)!: add limit to total amount of transactions in parked (#1638)
Summary
We want to order blocks by the transaction categories introduced in #1512 to finish the goals of #1412.
Background
Certain transactions have the ability to cause other transactions to become invalid. For example,
FeeChangeActionscan cause transactions that were valid to become invalid. For the sake of UX we want to order the potentially-invalidating actions after others so we don't needlessly execute transactions that were just invalidated. More background can be found in #1412.Changes
prepare_proposalbyActionGroup.prepare_proposalwill now skip any transactions in it's block construction process that are out of group order.process_proposalwill now reject any blocks that contain out-of-order transactions.Note: the mempool does not check for out of order actions inside of the pending queue. This was decided because the amount of times that actions besides
BundleableGeneralare expected to be ran is low. Instead we letprepare_proposalgracefully ignore out-of-order actions in a way that allows them to be included in future blocks.For example, let's say an account sends these two transactions into the mempool:
tx_0: {nonce: 0, action_group: UnbundleableGeneral}tx_1: {nonce: 1, action_group: BundleableGeneral}The mempool will feed these transaction in the order of
{tx_1, tx_0}toprepare_proposal, which is correct on a group ordering level but incorrect on a nonce ordering level.prepare_proposalwill handle this by skippingtx_1and only includingtx_0in the block. The mempool will re-feedtx_1on the next round toprepare_proposalto be included.Testing
Unit tests and ran locally.
Breaking Changelist
Block that would've passed before with incorrect transaction ordering will now fail.
Related Issues
closes #1412 #1417