-
Notifications
You must be signed in to change notification settings - Fork 11
WIRE-301: Retire legacy staking attestations #544
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
base: master
Are you sure you want to change the base?
Changes from 3 commits
9ad3b45
db54a6e
1672016
e394e85
c31b607
5f501d6
2c29ce1
4f19c71
90e92f5
44bf242
f74fd17
b77bdde
c2c10fa
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -361,6 +361,8 @@ constexpr uint64_t SOL_OUTPOST_ID = "SOL"_s.value; | |
| constexpr auto EVM_TEST_ATTESTATION_TYPE = opp::types::ATTESTATION_TYPE_OPERATORS; | ||
| constexpr auto SWAP_REMIT_ATTESTATION_TYPE = opp::types::ATTESTATION_TYPE_SWAP_REMIT; | ||
| constexpr auto UNCOVERED_TEST_ATTESTATION_TYPE = opp::types::ATTESTATION_TYPE_STAKING_REWARD; | ||
| /// Raw protobuf wire slot used only to seed the pre-upgrade READY-row shape. | ||
| constexpr uint32_t RETIRED_STAKE_ATTESTATION_VALUE = 3001; | ||
|
|
||
| /// Decode the emitted OPP envelope and count attestations in its single message. | ||
| uint32_t emitted_attestation_count(const fc::variant& emitted_row) { | ||
|
|
@@ -404,6 +406,31 @@ BOOST_FIXTURE_TEST_CASE(buildenv_writes_envlog_row, sysio_msgch_envlog_tester) { | |
| BOOST_REQUIRE_EQUAL(31337u, row["endpoints"]["end"]["id"]["value"].as_uint64()); | ||
| } FC_LOG_AND_RETHROW() } | ||
|
|
||
| /// READY rows written by a pre-upgrade contract with a retired staking wire | ||
| /// value are tombstoned before destination-specific envelope construction. | ||
| /// Active rows behind the tombstone still emit normally, so one legacy row | ||
| /// cannot strand the queue or reach an outpost decoder. | ||
| BOOST_FIXTURE_TEST_CASE(buildenv_tombstones_retired_staking_rows, | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Coverage gap: this only exercises the EVM path. The scenario the tombstone primarily protects against is the SVM one — where an untombstoned retired row hits Also untested: the retired-row-is-the-last-READY-row case, where Both are cheap additions to this same fixture. |
||
| sysio_msgch_envlog_tester) { try { | ||
| bootstrap_epoch_config(/*retention=*/200); | ||
| register_outpost(opp::types::CHAIN_KIND_EVM, 31337); | ||
| produce_blocks(); | ||
|
|
||
| BOOST_REQUIRE_EQUAL(success(), | ||
| queueout(/*chain_code=*/ETH_OUTPOST_ID, RETIRED_STAKE_ATTESTATION_VALUE)); | ||
| BOOST_REQUIRE_EQUAL(success(), | ||
| queueout(/*chain_code=*/ETH_OUTPOST_ID, EVM_TEST_ATTESTATION_TYPE)); | ||
| BOOST_REQUIRE_EQUAL(2u, count_ready_attestations(ETH_OUTPOST_ID, 8)); | ||
|
|
||
| BOOST_REQUIRE_EQUAL(success(), buildenv(/*chain_code=*/ETH_OUTPOST_ID)); | ||
| produce_blocks(); | ||
|
|
||
| BOOST_REQUIRE_EQUAL(0u, count_ready_attestations(ETH_OUTPOST_ID, 8)); | ||
| const auto emitted = find_outbound_envelope(); | ||
| BOOST_REQUIRE(!emitted.is_null()); | ||
| BOOST_REQUIRE_EQUAL(1u, emitted_attestation_count(emitted)); | ||
| } FC_LOG_AND_RETHROW() } | ||
|
|
||
| /// Eviction at the boundary. Set `retention=2` and one outpost → | ||
| /// `cap = 1*2*2 = 4`. After 5 buildenv rounds (5 rows inserted), the | ||
| /// oldest full epoch (`per_epoch = 1*2 = 2` rows) gets evicted; final | ||
|
|
||
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.
Unbounded prune inside an inline action.
This erases every retired READY row across all chains in a single transaction, and
buildenvruns as an inline action insidesysio.epoch::advance.If the residual legacy row count is large enough that N × (primary erase + 3 secondary-index erases) exceeds the transaction CPU budget,
advancereverts. The erases roll back with it, so every subsequentadvanceretries the identical work and reverts again — a deterministic, non-self-healing epoch stall.The immediately preceding master commit (
3673936b9f, uwrit UWREQ expiry) used bounded epoch-driven pruning for this same class of migration. A per-call cap plus a "skip, don't candidate" branch for the over-budget remainder would make this drain across epochs instead of all-or-nothing.Rating this low because the realistic residual count is small — an EVM-bound STAKE row would already have been packed and drained by the pre-upgrade contract, so only SVM-bound rows survive — but the failure mode has no recovery path if it does land.
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.
Addressed on current head 2c29ce1. buildenv caps retired-row erasure at 32 per call and continues skipping every over-budget retired row as an envelope candidate, so cleanup drains deterministically across calls without forwarding tombstones or turning one advance into an unbounded erase sweep. Coverage includes 33 retired rows followed by an active row; the active row emits and exactly one tombstone remains READY.