From 14c832460e12fbb768ec4dd946eff3f318383986 Mon Sep 17 00:00:00 2001 From: Huang-Ming Huang Date: Tue, 18 Aug 2026 17:59:27 +0000 Subject: [PATCH 01/17] Fix WIRE-344 slash before termination Change-Id: I292c7b7f9b38e0aeb6af0f8223db34777032fc0a --- contracts/sysio.epoch/src/sysio.epoch.cpp | 48 ++++++++++----- contracts/tests/sysio.msgch_chain_tests.cpp | 67 +++++++++++++++++++-- 2 files changed, 94 insertions(+), 21 deletions(-) diff --git a/contracts/sysio.epoch/src/sysio.epoch.cpp b/contracts/sysio.epoch/src/sysio.epoch.cpp index b796376345..6724740bae 100644 --- a/contracts/sysio.epoch/src/sysio.epoch.cpp +++ b/contracts/sysio.epoch/src/sysio.epoch.cpp @@ -440,9 +440,9 @@ void epoch::advance() { // For each (outpost × member of the expiring group): // - scan `msgch::envelopes` (`byoutepoch` index) for any row matching // (chain_code, current_epoch_index, batch_op_name == member) - // - inline `opreg::recorddel(member, current_epoch_index, did_deliver)` - // - inline `opreg::termcheck(member)` — the threshold + window come - // from `op_config`, so tests dial the thresholds via setconfig + // - collect the delivery result and every non-canonical deliverer + // - slash all non-canonical deliverers before delivery accounting can + // terminate them, then record the result and run `termcheck` // // The outpost set is sourced via a cross-contract read of // `sysio.chains::chains` (no local mirror) filtered to @@ -469,6 +469,15 @@ void epoch::advance() { // operator, which would abort advance and stall the chain). std::vector to_slash; + /// A delivery result retained until non-canonical offenders have been + /// slashed. `recorddel` remains an audit record even for a newly + /// slashed operator, while `termcheck` safely skips non-ACTIVE rows. + struct delivery_observation { + name member; + bool did_deliver; + }; + std::vector observations; + sysio::chains::chains_t chains_tbl(CHAINS_ACCOUNT); for (auto op_it = chains_tbl.begin(); op_it != chains_tbl.end(); ++op_it) { if (!is_active_outpost(*op_it)) continue; @@ -520,22 +529,11 @@ void epoch::advance() { break; } } - action( - permission_level{get_self(), "owner"_n}, - OPREG_ACCOUNT, - "recorddel"_n, - std::make_tuple(member, state.current_epoch_index, did_deliver) - ).send(); - action( - permission_level{get_self(), "owner"_n}, - OPREG_ACCOUNT, - "termcheck"_n, - std::make_tuple(member) - ).send(); + observations.push_back({member, did_deliver}); // Single slash path (dispute-vote design, per-operator outcome table): a delivered // NON-canonical checksum is a fault -> slash. Silence (no delivery) is never slashed; it - // stays on the recorddel/termcheck miss ladder above. Collect here; flush once below. + // stays on the recorddel/termcheck miss ladder below. Collect here; flush once below. if (did_deliver && have_winner && member_checksum != winner) { bool queued = false; for (const auto& s : to_slash) { @@ -572,6 +570,24 @@ void epoch::advance() { ).send(); } + // Preserve the delivery history after slashing. A non-canonical operator is already + // SLASHED here, so opreg::termcheck returns without converting the punitive outcome into a + // termination/remit. Other group members retain their normal delivery accounting. + for (const auto& observation : observations) { + action( + permission_level{get_self(), "owner"_n}, + OPREG_ACCOUNT, + "recorddel"_n, + std::make_tuple(observation.member, state.current_epoch_index, observation.did_deliver) + ).send(); + action( + permission_level{get_self(), "owner"_n}, + OPREG_ACCOUNT, + "termcheck"_n, + std::make_tuple(observation.member) + ).send(); + } + // NOTE: we intentionally do NOT erase the per-batch-op envelope // metadata rows here. `evalcons` already cleared their heavy // `raw_data` (1-2 KB → 0 bytes) at consensus reach, so the residual diff --git a/contracts/tests/sysio.msgch_chain_tests.cpp b/contracts/tests/sysio.msgch_chain_tests.cpp index a8ed123bd5..8bf1b9524f 100644 --- a/contracts/tests/sysio.msgch_chain_tests.cpp +++ b/contracts/tests/sysio.msgch_chain_tests.cpp @@ -178,10 +178,10 @@ class sysio_msgch_chain_tester : public tester { ("pay_cadence_epochs", uint16_t(1)))); } - /// Epoch + opreg config, bootstrapped batch ops (`BATCHOP` always; `BATCHOP_B`/`BATCHOP_C` when - /// `n_batch_ops` is 3 -- a single group of three, so consensus needs more than one delivery), - /// ETH + SOL chain rows, group schedule, genesis advance. - void bootstrap(uint32_t n_batch_ops = 1) { + /// Epoch + opreg config, a configurable `BATCHOP` plus bootstrapped `BATCHOP_B`/`BATCHOP_C` when + /// `n_batch_ops` is 3 (a single group of three, so consensus needs more than one delivery), ETH + + /// SOL chain rows, group schedule, and genesis advance. + void bootstrap(uint32_t n_batch_ops = 1, bool batchop_is_bootstrapped = true) { BOOST_REQUIRE_EQUAL(success(), push(EPOCH_ACCOUNT, epoch_abi, EPOCH_ACCOUNT, "setconfig"_n, mvo() ("epoch_duration_sec", EPOCH_DURATION_SEC) @@ -221,12 +221,18 @@ class sysio_msgch_chain_tester : public tester { "regoperator"_n, mvo() ("account", op.to_string()) ("type", opp::types::OperatorType::OPERATOR_TYPE_BATCH) - ("is_bootstrapped", true))); + ("is_bootstrapped", op == BATCHOP ? batchop_is_bootstrapped : true))); } register_chain(opp::types::ChainKind::CHAIN_KIND_EVM, "ETH", 31337); register_chain(opp::types::ChainKind::CHAIN_KIND_SVM, "SOL", 1); + // A non-bootstrapped batch operator starts UNKNOWN and becomes ACTIVE + // only after a collateral update re-evaluates its role eligibility. + if (!batchop_is_bootstrapped) { + BOOST_REQUIRE_EQUAL(success(), depositinle(BATCHOP, "ETH", "ETH", 1)); + } + BOOST_REQUIRE_EQUAL(success(), push(EPOCH_ACCOUNT, epoch_abi, EPOCH_ACCOUNT, "schbatchgps"_n, mvo())); @@ -278,6 +284,15 @@ class sysio_msgch_chain_tester : public tester { ("data", data)); } + /// Seed a historical delivery outcome under epoch authority so the next + /// real epoch advance exercises the rolling termination threshold. + action_result record_delivery(name account, uint32_t epoch, bool delivered) { + return push(OPREG_ACCOUNT, opreg_abi, EPOCH_ACCOUNT, "recorddel"_n, mvo() + ("account", account.to_string()) + ("epoch", epoch) + ("delivered", delivered)); + } + /// Let the consensus boundary elapse WITHOUT advancing the epoch: evalcons' fallback /// (majority) path opens once `epoch_duration_sec` has passed since the epoch started, /// while `deliver`'s epoch gate keeps accepting envelopes for the still-current epoch. @@ -1126,6 +1141,48 @@ BOOST_FIXTURE_TEST_CASE(late_confirmation_after_consensus_recorded, sysio_msgch_ } } FC_LOG_AND_RETHROW() } +/// WNS-16: a non-canonical delivery must be slashed before its historical +/// miss window can terminate it. The last canonical delivery reaches +/// consensus for both outposts and drives the real `chkcons -> advance` +/// path; pre-fix, `termcheck` marked BATCHOP TERMINATED before `slashop` +/// rejected that state and rolled the entire epoch back. +BOOST_FIXTURE_TEST_CASE(noncanonical_delivery_slashes_before_termination, sysio_msgch_chain_tester) { try { + constexpr uint32_t kMaxConsecutiveMisses = 5; + + bootstrap(/*n_batch_ops=*/3, /*batchop_is_bootstrapped=*/false); + BOOST_REQUIRE_EQUAL(opp::types::OperatorStatus::OPERATOR_STATUS_ACTIVE, + get_operator(BATCHOP)["status"].as()); + + // Seed enough prior misses for the next termcheck to terminate BATCHOP if + // it remains ACTIVE. The current epoch's non-canonical delivery still + // counts as delivered, so this specifically covers the ordering conflict. + for (uint32_t prior_epoch = 1; prior_epoch <= kMaxConsecutiveMisses + 1; ++prior_epoch) { + BOOST_REQUIRE_EQUAL(success(), record_delivery(BATCHOP, prior_epoch, /*delivered=*/false)); + produce_blocks(); + } + + const uint32_t epoch = current_epoch(); + const auto canonical = encode_delivery(epoch, "canonical"); + const auto divergent = encode_delivery(epoch, "non-canonical"); + + // Stage the split ETH deliveries and one SOL delivery before the boundary. + // The two remaining canonical deliveries reach majority after the boundary; + // the SOL delivery invokes chkcons, which advances the epoch inline. + BOOST_REQUIRE_EQUAL(success(), deliver_as(BATCHOP, ETH_OUTPOST_ID, divergent)); + BOOST_REQUIRE_EQUAL(success(), deliver_as(BATCHOP_B, ETH_OUTPOST_ID, canonical)); + BOOST_REQUIRE_EQUAL(success(), deliver_as(BATCHOP, SOL_OUTPOST_ID, canonical)); + elapse_epoch_boundary(); + BOOST_REQUIRE_EQUAL(success(), deliver_as(BATCHOP_C, ETH_OUTPOST_ID, canonical)); + BOOST_REQUIRE_EQUAL(success(), deliver_as(BATCHOP_B, SOL_OUTPOST_ID, canonical)); + produce_blocks(); + + auto op = get_operator(BATCHOP); + BOOST_REQUIRE_EQUAL(opp::types::OperatorStatus::OPERATOR_STATUS_SLASHED, + op["status"].as()); + BOOST_REQUIRE_EQUAL(epoch + 1, current_epoch()); + BOOST_REQUIRE_EQUAL(2u, delivered_dellog_count(BATCHOP)); +} FC_LOG_AND_RETHROW() } + // SEC-28 (huang review): terminate on the CONSECUTIVE-miss rail through the REAL rotation -- a // materialized three-group schedule driven by advance() with one outpost, at exactly the minimum // window the span bound accepts. A resident operator is on duty once per three-epoch rotation, and From 4e70ce9f63b9cb790dd09c10095b7c8bb45918ca Mon Sep 17 00:00:00 2001 From: Huang-Ming Huang Date: Tue, 18 Aug 2026 18:46:18 +0000 Subject: [PATCH 02/17] Fix WIRE-344 regression fixture Change-Id: If39d46c11c2a47ec968405d9fef368c96388499b --- contracts/tests/sysio.msgch_chain_tests.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/contracts/tests/sysio.msgch_chain_tests.cpp b/contracts/tests/sysio.msgch_chain_tests.cpp index 8bf1b9524f..46631e5c32 100644 --- a/contracts/tests/sysio.msgch_chain_tests.cpp +++ b/contracts/tests/sysio.msgch_chain_tests.cpp @@ -208,7 +208,12 @@ class sysio_msgch_chain_tester : public tester { ("terminate_max_pct_misses_24h", 5) ("terminate_window_ms", uint64_t{24ULL * 60 * 60 * 1000}) ("req_prod_collat", fc::variants{}) - ("req_batchop_collat", fc::variants{}) + // Empty collateral requirements intentionally keep non-bootstrapped + // operators UNKNOWN. Give the WNS-16 fixture's non-bootstrapped + // operator the one-unit ETH requirement it satisfies below. + ("req_batchop_collat", batchop_is_bootstrapped + ? fc::variants{} + : fc::variants{ make_chain_min_bond("ETH", "ETH", 1) }) ("req_uw_collat", fc::variants{}))); std::vector batch_ops{BATCHOP}; From f43743da499f445cfdbdbfa371112b006c49b863 Mon Sep 17 00:00:00 2001 From: Huang-Ming Huang Date: Tue, 18 Aug 2026 18:59:01 +0000 Subject: [PATCH 03/17] Assert WIRE-344 fixture epoch precondition Change-Id: I27f8c04eabcafa25870d73751e4cb9630ae190d6 --- contracts/tests/sysio.msgch_chain_tests.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/contracts/tests/sysio.msgch_chain_tests.cpp b/contracts/tests/sysio.msgch_chain_tests.cpp index 46631e5c32..1a81d6f7cc 100644 --- a/contracts/tests/sysio.msgch_chain_tests.cpp +++ b/contracts/tests/sysio.msgch_chain_tests.cpp @@ -1155,6 +1155,7 @@ BOOST_FIXTURE_TEST_CASE(noncanonical_delivery_slashes_before_termination, sysio_ constexpr uint32_t kMaxConsecutiveMisses = 5; bootstrap(/*n_batch_ops=*/3, /*batchop_is_bootstrapped=*/false); + BOOST_REQUIRE_EQUAL(1u, current_epoch()); BOOST_REQUIRE_EQUAL(opp::types::OperatorStatus::OPERATOR_STATUS_ACTIVE, get_operator(BATCHOP)["status"].as()); From a0b7e024d5185ea55e2333680212adf79a6f097d Mon Sep 17 00:00:00 2001 From: Huang-Ming Huang Date: Tue, 18 Aug 2026 19:04:48 +0000 Subject: [PATCH 04/17] Drive WIRE-344 regression through chkcons Change-Id: Iddbc2cacdd7aba495a17e41145bf0f93dd889e6d --- contracts/tests/sysio.msgch_chain_tests.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/contracts/tests/sysio.msgch_chain_tests.cpp b/contracts/tests/sysio.msgch_chain_tests.cpp index 1a81d6f7cc..a609ea4021 100644 --- a/contracts/tests/sysio.msgch_chain_tests.cpp +++ b/contracts/tests/sysio.msgch_chain_tests.cpp @@ -1173,13 +1173,15 @@ BOOST_FIXTURE_TEST_CASE(noncanonical_delivery_slashes_before_termination, sysio_ // Stage the split ETH deliveries and one SOL delivery before the boundary. // The two remaining canonical deliveries reach majority after the boundary; - // the SOL delivery invokes chkcons, which advances the epoch inline. + // then the permissionless chkcons crank advances the epoch inline. BOOST_REQUIRE_EQUAL(success(), deliver_as(BATCHOP, ETH_OUTPOST_ID, divergent)); BOOST_REQUIRE_EQUAL(success(), deliver_as(BATCHOP_B, ETH_OUTPOST_ID, canonical)); BOOST_REQUIRE_EQUAL(success(), deliver_as(BATCHOP, SOL_OUTPOST_ID, canonical)); elapse_epoch_boundary(); BOOST_REQUIRE_EQUAL(success(), deliver_as(BATCHOP_C, ETH_OUTPOST_ID, canonical)); BOOST_REQUIRE_EQUAL(success(), deliver_as(BATCHOP_B, SOL_OUTPOST_ID, canonical)); + BOOST_REQUIRE_EQUAL(success(), push(MSGCH_ACCOUNT, msgch_abi, MSGCH_ACCOUNT, + "chkcons"_n, mvo())); produce_blocks(); auto op = get_operator(BATCHOP); From 2d52da8e39d2d5a3f4b141a0cfef80fadd36d8c0 Mon Sep 17 00:00:00 2001 From: Huang-Ming Huang Date: Tue, 18 Aug 2026 19:10:13 +0000 Subject: [PATCH 05/17] Assert WIRE-344 canonical consensus outcome Change-Id: I14c08bc8c66b64504b431cb209000906bb81c1d2 --- contracts/tests/sysio.msgch_chain_tests.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/contracts/tests/sysio.msgch_chain_tests.cpp b/contracts/tests/sysio.msgch_chain_tests.cpp index a609ea4021..182721f3d2 100644 --- a/contracts/tests/sysio.msgch_chain_tests.cpp +++ b/contracts/tests/sysio.msgch_chain_tests.cpp @@ -1170,6 +1170,9 @@ BOOST_FIXTURE_TEST_CASE(noncanonical_delivery_slashes_before_termination, sysio_ const uint32_t epoch = current_epoch(); const auto canonical = encode_delivery(epoch, "canonical"); const auto divergent = encode_delivery(epoch, "non-canonical"); + const auto canonical_checksum = fc::sha256::hash(canonical.data(), canonical.size()); + const auto divergent_checksum = fc::sha256::hash(divergent.data(), divergent.size()); + BOOST_REQUIRE_NE(canonical_checksum, divergent_checksum); // Stage the split ETH deliveries and one SOL delivery before the boundary. // The two remaining canonical deliveries reach majority after the boundary; @@ -1179,6 +1182,12 @@ BOOST_FIXTURE_TEST_CASE(noncanonical_delivery_slashes_before_termination, sysio_ BOOST_REQUIRE_EQUAL(success(), deliver_as(BATCHOP, SOL_OUTPOST_ID, canonical)); elapse_epoch_boundary(); BOOST_REQUIRE_EQUAL(success(), deliver_as(BATCHOP_C, ETH_OUTPOST_ID, canonical)); + { + auto eth_consensus = get_outpcons(ETH_OUTPOST_ID); + BOOST_REQUIRE(!eth_consensus.is_null()); + BOOST_REQUIRE_EQUAL(epoch, eth_consensus["epoch_index"].as()); + BOOST_REQUIRE_EQUAL(canonical_checksum.str(), eth_consensus["winning_checksum"].as_string()); + } BOOST_REQUIRE_EQUAL(success(), deliver_as(BATCHOP_B, SOL_OUTPOST_ID, canonical)); BOOST_REQUIRE_EQUAL(success(), push(MSGCH_ACCOUNT, msgch_abi, MSGCH_ACCOUNT, "chkcons"_n, mvo())); From ed8e9476297cf24f72cafabe1145a98aa3405cd6 Mon Sep 17 00:00:00 2001 From: Huang-Ming Huang Date: Tue, 18 Aug 2026 19:16:01 +0000 Subject: [PATCH 06/17] Assert WIRE-344 slash classification inputs Change-Id: Iba0e1f62c248adece4c2a49ef3f43d4e681402cc --- contracts/tests/sysio.msgch_chain_tests.cpp | 29 +++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/contracts/tests/sysio.msgch_chain_tests.cpp b/contracts/tests/sysio.msgch_chain_tests.cpp index 182721f3d2..ee00753207 100644 --- a/contracts/tests/sysio.msgch_chain_tests.cpp +++ b/contracts/tests/sysio.msgch_chain_tests.cpp @@ -344,6 +344,22 @@ class sysio_msgch_chain_tester : public tester { abi_serializer::create_yield_function(abi_serializer_max_time)); } + /// Inbound delivery metadata for one (outpost, epoch, batch operator), or null when absent. + /// Consensus deliberately clears only raw_data, leaving this row for advance() to classify. + fc::variant find_inbound_delivery(uint64_t chain_code, uint32_t epoch_index, name batch_op, + uint64_t scan_until = 64) { + for (uint64_t id = 0; id < scan_until; ++id) { + auto data = get_row_by_id(MSGCH_ACCOUNT, MSGCH_ACCOUNT, "envelopes"_n, id); + if (data.empty()) continue; + auto row = msgch_abi.binary_to_variant( + "envelope_entry", data, abi_serializer::create_yield_function(abi_serializer_max_time)); + if (row["chain_code"].as_uint64() == chain_code && + row["epoch_index"].as() == epoch_index && + row["batch_op_name"].as_string() == batch_op.to_string()) return row; + } + return fc::variant{}; + } + /// Count attestation rows recorded for (`chain_code`, `epoch_index`); the observable effect /// of an ACCEPTED inbound envelope (rows are emplaced before dispatch, even for types /// dispatch drops as out of scope). @@ -1158,6 +1174,16 @@ BOOST_FIXTURE_TEST_CASE(noncanonical_delivery_slashes_before_termination, sysio_ BOOST_REQUIRE_EQUAL(1u, current_epoch()); BOOST_REQUIRE_EQUAL(opp::types::OperatorStatus::OPERATOR_STATUS_ACTIVE, get_operator(BATCHOP)["status"].as()); + { + auto state = read_epoch_state(); + auto groups = state["batch_op_groups"].get_array(); + auto active_group = groups[state["current_batch_op_group"].as_uint64()].get_array(); + bool batchop_is_scheduled = false; + for (const auto& member : active_group) { + if (member.as_string() == BATCHOP.to_string()) batchop_is_scheduled = true; + } + BOOST_REQUIRE(batchop_is_scheduled); + } // Seed enough prior misses for the next termcheck to terminate BATCHOP if // it remains ACTIVE. The current epoch's non-canonical delivery still @@ -1187,6 +1213,9 @@ BOOST_FIXTURE_TEST_CASE(noncanonical_delivery_slashes_before_termination, sysio_ BOOST_REQUIRE(!eth_consensus.is_null()); BOOST_REQUIRE_EQUAL(epoch, eth_consensus["epoch_index"].as()); BOOST_REQUIRE_EQUAL(canonical_checksum.str(), eth_consensus["winning_checksum"].as_string()); + auto divergent_delivery = find_inbound_delivery(ETH_OUTPOST_ID, epoch, BATCHOP); + BOOST_REQUIRE(!divergent_delivery.is_null()); + BOOST_REQUIRE_EQUAL(divergent_checksum.str(), divergent_delivery["checksum"].as_string()); } BOOST_REQUIRE_EQUAL(success(), deliver_as(BATCHOP_B, SOL_OUTPOST_ID, canonical)); BOOST_REQUIRE_EQUAL(success(), push(MSGCH_ACCOUNT, msgch_abi, MSGCH_ACCOUNT, From edd29fa3101938c77dd448d5e006fd668a185f59 Mon Sep 17 00:00:00 2001 From: Huang-Ming Huang Date: Tue, 18 Aug 2026 19:20:19 +0000 Subject: [PATCH 07/17] Deploy slashing path for WIRE-344 regression Change-Id: I69bef6855da5aa696ee5826048e01588c63b25a8 --- contracts/tests/sysio.msgch_chain_tests.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/contracts/tests/sysio.msgch_chain_tests.cpp b/contracts/tests/sysio.msgch_chain_tests.cpp index ee00753207..5128ba2b93 100644 --- a/contracts/tests/sysio.msgch_chain_tests.cpp +++ b/contracts/tests/sysio.msgch_chain_tests.cpp @@ -95,6 +95,7 @@ class sysio_msgch_chain_tester : public tester { }); produce_blocks(2); + deploy(CHALG_ACCOUNT, contracts::chalg_wasm(), contracts::chalg_abi(), chalg_abi); deploy(EPOCH_ACCOUNT, contracts::epoch_wasm(), contracts::epoch_abi(), epoch_abi); deploy(OPREG_ACCOUNT, contracts::opreg_wasm(), contracts::opreg_abi(), opreg_abi); deploy(MSGCH_ACCOUNT, contracts::msgch_wasm(), contracts::msgch_abi(), msgch_abi); @@ -553,7 +554,7 @@ class sysio_msgch_chain_tester : public tester { produce_blocks(); } - abi_serializer sysio_abi, token_abi, epoch_abi, opreg_abi, msgch_abi, chains_abi, uwrit_abi; + abi_serializer sysio_abi, token_abi, epoch_abi, opreg_abi, msgch_abi, chalg_abi, chains_abi, uwrit_abi; }; // --------------------------------------------------------------------------- From 32258884851e87e23f476d628ec8cd567e0a6bbf Mon Sep 17 00:00:00 2001 From: Huang-Ming Huang Date: Tue, 18 Aug 2026 19:37:10 +0000 Subject: [PATCH 08/17] Strengthen WIRE-344 regression coverage Change-Id: I99d1c2220d05d732d0491f631a05885cf737b47e --- contracts/sysio.epoch/src/sysio.epoch.cpp | 3 +- contracts/tests/sysio.msgch_chain_tests.cpp | 53 +++++++++++++++++---- 2 files changed, 45 insertions(+), 11 deletions(-) diff --git a/contracts/sysio.epoch/src/sysio.epoch.cpp b/contracts/sysio.epoch/src/sysio.epoch.cpp index 6724740bae..c854924cb6 100644 --- a/contracts/sysio.epoch/src/sysio.epoch.cpp +++ b/contracts/sysio.epoch/src/sysio.epoch.cpp @@ -44,6 +44,7 @@ namespace { constexpr name SYSTEM_ACCOUNT = "sysio"_n; constexpr name TOKEN_ACCOUNT = "sysio.token"_n; +constexpr name CHALG_SLASHOP_ACTION = "slashop"_n; // System-owned rows are billed to the sysio RAM pool rather than to this contract account (the // privileged-contract model sysio.token uses): the contract account stays finite at its code+abi @@ -563,7 +564,7 @@ void epoch::advance() { action( permission_level{get_self(), "owner"_n}, CHALG_ACCOUNT, - "slashop"_n, + CHALG_SLASHOP_ACTION, std::make_tuple(member, std::string("non-canonical OPP envelope delivery, epoch ") + std::to_string(state.current_epoch_index)) diff --git a/contracts/tests/sysio.msgch_chain_tests.cpp b/contracts/tests/sysio.msgch_chain_tests.cpp index 5128ba2b93..13409039dc 100644 --- a/contracts/tests/sysio.msgch_chain_tests.cpp +++ b/contracts/tests/sysio.msgch_chain_tests.cpp @@ -58,6 +58,10 @@ using fc::slug_name_literals::operator""_s; constexpr uint64_t ETH_OUTPOST_ID = "ETH"_s.value; constexpr uint64_t SOL_OUTPOST_ID = "SOL"_s.value; +constexpr std::string_view ETH_CHAIN_CODE = "ETH"; +constexpr std::string_view SOL_CHAIN_CODE = "SOL"; +constexpr uint64_t BATCHOP_MIN_COLLATERAL = 1; +constexpr uint64_t TABLE_SCAN_LIMIT = 64; } // anonymous namespace @@ -211,10 +215,14 @@ class sysio_msgch_chain_tester : public tester { ("req_prod_collat", fc::variants{}) // Empty collateral requirements intentionally keep non-bootstrapped // operators UNKNOWN. Give the WNS-16 fixture's non-bootstrapped - // operator the one-unit ETH requirement it satisfies below. + // operator the one-unit ETH and SOL requirements it satisfies below. ("req_batchop_collat", batchop_is_bootstrapped ? fc::variants{} - : fc::variants{ make_chain_min_bond("ETH", "ETH", 1) }) + : fc::variants{ + make_chain_min_bond(ETH_CHAIN_CODE, ETH_CHAIN_CODE, + BATCHOP_MIN_COLLATERAL), + make_chain_min_bond(SOL_CHAIN_CODE, SOL_CHAIN_CODE, + BATCHOP_MIN_COLLATERAL) }) ("req_uw_collat", fc::variants{}))); std::vector batch_ops{BATCHOP}; @@ -230,13 +238,17 @@ class sysio_msgch_chain_tester : public tester { ("is_bootstrapped", op == BATCHOP ? batchop_is_bootstrapped : true))); } - register_chain(opp::types::ChainKind::CHAIN_KIND_EVM, "ETH", 31337); - register_chain(opp::types::ChainKind::CHAIN_KIND_SVM, "SOL", 1); + register_chain(opp::types::ChainKind::CHAIN_KIND_EVM, ETH_CHAIN_CODE, 31337); + register_chain(opp::types::ChainKind::CHAIN_KIND_SVM, SOL_CHAIN_CODE, 1); // A non-bootstrapped batch operator starts UNKNOWN and becomes ACTIVE // only after a collateral update re-evaluates its role eligibility. if (!batchop_is_bootstrapped) { - BOOST_REQUIRE_EQUAL(success(), depositinle(BATCHOP, "ETH", "ETH", 1)); + BOOST_REQUIRE_EQUAL(success(), depositinle(BATCHOP, ETH_CHAIN_CODE, ETH_CHAIN_CODE, + BATCHOP_MIN_COLLATERAL)); + BOOST_REQUIRE_EQUAL(success(), depositinle(BATCHOP, SOL_CHAIN_CODE, SOL_CHAIN_CODE, + BATCHOP_MIN_COLLATERAL, + opp::types::ChainKind::CHAIN_KIND_SVM)); } BOOST_REQUIRE_EQUAL(success(), push(EPOCH_ACCOUNT, epoch_abi, EPOCH_ACCOUNT, @@ -348,7 +360,7 @@ class sysio_msgch_chain_tester : public tester { /// Inbound delivery metadata for one (outpost, epoch, batch operator), or null when absent. /// Consensus deliberately clears only raw_data, leaving this row for advance() to classify. fc::variant find_inbound_delivery(uint64_t chain_code, uint32_t epoch_index, name batch_op, - uint64_t scan_until = 64) { + uint64_t scan_until = TABLE_SCAN_LIMIT) { for (uint64_t id = 0; id < scan_until; ++id) { auto data = get_row_by_id(MSGCH_ACCOUNT, MSGCH_ACCOUNT, "envelopes"_n, id); if (data.empty()) continue; @@ -365,7 +377,7 @@ class sysio_msgch_chain_tester : public tester { /// of an ACCEPTED inbound envelope (rows are emplaced before dispatch, even for types /// dispatch drops as out of scope). uint32_t attestation_count(uint64_t chain_code, uint32_t epoch_index, - uint64_t scan_until = 64) { + uint64_t scan_until = TABLE_SCAN_LIMIT) { uint32_t n = 0; for (uint64_t id = 0; id < scan_until; ++id) { auto data = get_row_by_id(MSGCH_ACCOUNT, MSGCH_ACCOUNT, "attestations"_n, id); @@ -429,10 +441,28 @@ class sysio_msgch_chain_tester : public tester { "operator_entry", data, abi_serializer::create_yield_function(abi_serializer_max_time)); } + /// Count successful SLASH audit entries for `account` routed to `chain_code`. + /// opreg emits and logs one action for each immediately slashable collateral balance. + uint32_t slash_action_count(name account, uint64_t chain_code) { + auto op = get_operator(account); + if (op.is_null()) return 0; + + uint32_t n = 0; + for (const auto& log : op["recent_actions"].get_array()) { + const auto& action = log["action"]; + if (!log["success"].as_bool() || + action["action_type"].as() != + sysio::opp::attestations::OperatorAction::ACTION_TYPE_SLASH || + action["chain_code"].as_uint64() != chain_code) continue; + ++n; + } + return n; + } + /// Count DELIVERED dellog rows still present for `account`. recorddel PRUNES (erases) rows that /// have aged out of the rolling window, so a surviving delivered row proves that record is still /// inside the window -- the direct check that the edge anchor was not pruned. - uint32_t delivered_dellog_count(name account, uint64_t scan_until = 64) { + uint32_t delivered_dellog_count(name account, uint64_t scan_until = TABLE_SCAN_LIMIT) { uint32_t n = 0; for (uint64_t id = 0; id < scan_until; ++id) { auto data = get_row_by_account(OPREG_ACCOUNT, OPREG_ACCOUNT, "dellog"_n, name{id}); @@ -490,13 +520,14 @@ class sysio_msgch_chain_tester : public tester { /// Inline collateral credit (the path sysio.msgch drives in production; pushed directly here) that /// lifts a non-bootstrapped operator to ACTIVE once its bond meets the configured minimum. action_result depositinle(name account, std::string_view chain_code, std::string_view token_code, - uint64_t amount) { + uint64_t amount, + opp::types::ChainKind actor_chain = opp::types::ChainKind::CHAIN_KIND_EVM) { return push(OPREG_ACCOUNT, opreg_abi, OPREG_ACCOUNT, "depositinle"_n, mvo() ("account", account.to_string()) ("chain_code", codename_mvo(chain_code)) ("token_code", codename_mvo(token_code)) ("amount", amount) - ("actor_chain", opp::types::ChainKind::CHAIN_KIND_EVM) + ("actor_chain", actor_chain) ("actor_address", std::vector{}) ("original_message_id", std::string(64, '0'))); } @@ -1226,6 +1257,8 @@ BOOST_FIXTURE_TEST_CASE(noncanonical_delivery_slashes_before_termination, sysio_ auto op = get_operator(BATCHOP); BOOST_REQUIRE_EQUAL(opp::types::OperatorStatus::OPERATOR_STATUS_SLASHED, op["status"].as()); + BOOST_REQUIRE_EQUAL(1u, slash_action_count(BATCHOP, ETH_OUTPOST_ID)); + BOOST_REQUIRE_EQUAL(1u, slash_action_count(BATCHOP, SOL_OUTPOST_ID)); BOOST_REQUIRE_EQUAL(epoch + 1, current_epoch()); BOOST_REQUIRE_EQUAL(2u, delivered_dellog_count(BATCHOP)); } FC_LOG_AND_RETHROW() } From ca8206771fbe2919a1e8500fb210dd7e6f8cfca2 Mon Sep 17 00:00:00 2001 From: Huang-Ming Huang Date: Tue, 18 Aug 2026 19:43:32 +0000 Subject: [PATCH 09/17] Fix WIRE-344 slash audit assertion Change-Id: I8d7c438318a066d38b38ade519fafdc27bf068af --- contracts/tests/sysio.msgch_chain_tests.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contracts/tests/sysio.msgch_chain_tests.cpp b/contracts/tests/sysio.msgch_chain_tests.cpp index 13409039dc..58f28044fb 100644 --- a/contracts/tests/sysio.msgch_chain_tests.cpp +++ b/contracts/tests/sysio.msgch_chain_tests.cpp @@ -60,6 +60,7 @@ constexpr uint64_t ETH_OUTPOST_ID = "ETH"_s.value; constexpr uint64_t SOL_OUTPOST_ID = "SOL"_s.value; constexpr std::string_view ETH_CHAIN_CODE = "ETH"; constexpr std::string_view SOL_CHAIN_CODE = "SOL"; +constexpr char SLASH_ACTION_TYPE[] = "ACTION_TYPE_SLASH"; constexpr uint64_t BATCHOP_MIN_COLLATERAL = 1; constexpr uint64_t TABLE_SCAN_LIMIT = 64; @@ -451,8 +452,7 @@ class sysio_msgch_chain_tester : public tester { for (const auto& log : op["recent_actions"].get_array()) { const auto& action = log["action"]; if (!log["success"].as_bool() || - action["action_type"].as() != - sysio::opp::attestations::OperatorAction::ACTION_TYPE_SLASH || + action["action_type"].as_string() != SLASH_ACTION_TYPE || action["chain_code"].as_uint64() != chain_code) continue; ++n; } From cbfd709c0c9a06fe151f7163024bdef5111979fc Mon Sep 17 00:00:00 2001 From: Huang-Ming Huang Date: Tue, 18 Aug 2026 20:01:20 +0000 Subject: [PATCH 10/17] Address WIRE-344 compliance review Change-Id: I1d1788e34495fffa02024101953107526a111468 --- contracts/sysio.epoch/src/sysio.epoch.cpp | 14 +++++-- contracts/tests/sysio.msgch_chain_tests.cpp | 45 ++++++++++++++------- 2 files changed, 42 insertions(+), 17 deletions(-) diff --git a/contracts/sysio.epoch/src/sysio.epoch.cpp b/contracts/sysio.epoch/src/sysio.epoch.cpp index c854924cb6..76cbd9f54a 100644 --- a/contracts/sysio.epoch/src/sysio.epoch.cpp +++ b/contracts/sysio.epoch/src/sysio.epoch.cpp @@ -44,7 +44,15 @@ namespace { constexpr name SYSTEM_ACCOUNT = "sysio"_n; constexpr name TOKEN_ACCOUNT = "sysio.token"_n; -constexpr name CHALG_SLASHOP_ACTION = "slashop"_n; + +/// Action identifiers owned by sysio.chalg and invoked by epoch close. +namespace chalg_actions { +constexpr name SLASHOP = "slashop"_n; +} // namespace chalg_actions + +/// Durable reason prefix for an epoch-delivery classification slash. +constexpr const char* NON_CANONICAL_DELIVERY_REASON_PREFIX = + "non-canonical OPP envelope delivery, epoch "; // System-owned rows are billed to the sysio RAM pool rather than to this contract account (the // privileged-contract model sysio.token uses): the contract account stays finite at its code+abi @@ -564,9 +572,9 @@ void epoch::advance() { action( permission_level{get_self(), "owner"_n}, CHALG_ACCOUNT, - CHALG_SLASHOP_ACTION, + chalg_actions::SLASHOP, std::make_tuple(member, - std::string("non-canonical OPP envelope delivery, epoch ") + std::string(NON_CANONICAL_DELIVERY_REASON_PREFIX) + std::to_string(state.current_epoch_index)) ).send(); } diff --git a/contracts/tests/sysio.msgch_chain_tests.cpp b/contracts/tests/sysio.msgch_chain_tests.cpp index 58f28044fb..2f3fc9afa5 100644 --- a/contracts/tests/sysio.msgch_chain_tests.cpp +++ b/contracts/tests/sysio.msgch_chain_tests.cpp @@ -60,7 +60,6 @@ constexpr uint64_t ETH_OUTPOST_ID = "ETH"_s.value; constexpr uint64_t SOL_OUTPOST_ID = "SOL"_s.value; constexpr std::string_view ETH_CHAIN_CODE = "ETH"; constexpr std::string_view SOL_CHAIN_CODE = "SOL"; -constexpr char SLASH_ACTION_TYPE[] = "ACTION_TYPE_SLASH"; constexpr uint64_t BATCHOP_MIN_COLLATERAL = 1; constexpr uint64_t TABLE_SCAN_LIMIT = 64; @@ -448,11 +447,17 @@ class sysio_msgch_chain_tester : public tester { auto op = get_operator(account); if (op.is_null()) return 0; + using operator_action_type = sysio::opp::attestations::OperatorAction_ActionType; uint32_t n = 0; for (const auto& log : op["recent_actions"].get_array()) { + operator_action_type action_type = + sysio::opp::attestations::OperatorAction_ActionType_ACTION_TYPE_UNKNOWN; const auto& action = log["action"]; - if (!log["success"].as_bool() || - action["action_type"].as_string() != SLASH_ACTION_TYPE || + const bool is_slash = + sysio::opp::attestations::OperatorAction_ActionType_Parse( + action["action_type"].as_string(), &action_type) && + action_type == sysio::opp::attestations::OperatorAction_ActionType_ACTION_TYPE_SLASH; + if (!log["success"].as_bool() || !is_slash || action["chain_code"].as_uint64() != chain_code) continue; ++n; } @@ -1200,10 +1205,18 @@ BOOST_FIXTURE_TEST_CASE(late_confirmation_after_consensus_recorded, sysio_msgch_ /// path; pre-fix, `termcheck` marked BATCHOP TERMINATED before `slashop` /// rejected that state and rolled the entire epoch back. BOOST_FIXTURE_TEST_CASE(noncanonical_delivery_slashes_before_termination, sysio_msgch_chain_tester) { try { - constexpr uint32_t kMaxConsecutiveMisses = 5; - - bootstrap(/*n_batch_ops=*/3, /*batchop_is_bootstrapped=*/false); - BOOST_REQUIRE_EQUAL(1u, current_epoch()); + constexpr uint32_t kBatchOperatorCount = 3; + constexpr uint32_t kExpectedInitialEpoch = 1; + constexpr uint32_t kMaxConsecutiveMisses = 5; + constexpr uint32_t kHistoricalMissesPastTerminationThreshold = 1; + constexpr const char* kCanonicalPayload = "canonical"; + constexpr const char* kNonCanonicalPayload = "non-canonical"; + constexpr uint32_t kExpectedSlashActionsPerOutpost = 1; + constexpr uint32_t kEpochAdvanceCount = 1; + constexpr uint32_t kExpectedDeliveredLogCount = 2; + + bootstrap(/*n_batch_ops=*/kBatchOperatorCount, /*batchop_is_bootstrapped=*/false); + BOOST_REQUIRE_EQUAL(kExpectedInitialEpoch, current_epoch()); BOOST_REQUIRE_EQUAL(opp::types::OperatorStatus::OPERATOR_STATUS_ACTIVE, get_operator(BATCHOP)["status"].as()); { @@ -1220,14 +1233,16 @@ BOOST_FIXTURE_TEST_CASE(noncanonical_delivery_slashes_before_termination, sysio_ // Seed enough prior misses for the next termcheck to terminate BATCHOP if // it remains ACTIVE. The current epoch's non-canonical delivery still // counts as delivered, so this specifically covers the ordering conflict. - for (uint32_t prior_epoch = 1; prior_epoch <= kMaxConsecutiveMisses + 1; ++prior_epoch) { + for (uint32_t prior_epoch = kExpectedInitialEpoch; + prior_epoch <= kMaxConsecutiveMisses + kHistoricalMissesPastTerminationThreshold; + ++prior_epoch) { BOOST_REQUIRE_EQUAL(success(), record_delivery(BATCHOP, prior_epoch, /*delivered=*/false)); produce_blocks(); } const uint32_t epoch = current_epoch(); - const auto canonical = encode_delivery(epoch, "canonical"); - const auto divergent = encode_delivery(epoch, "non-canonical"); + const auto canonical = encode_delivery(epoch, kCanonicalPayload); + const auto divergent = encode_delivery(epoch, kNonCanonicalPayload); const auto canonical_checksum = fc::sha256::hash(canonical.data(), canonical.size()); const auto divergent_checksum = fc::sha256::hash(divergent.data(), divergent.size()); BOOST_REQUIRE_NE(canonical_checksum, divergent_checksum); @@ -1257,10 +1272,12 @@ BOOST_FIXTURE_TEST_CASE(noncanonical_delivery_slashes_before_termination, sysio_ auto op = get_operator(BATCHOP); BOOST_REQUIRE_EQUAL(opp::types::OperatorStatus::OPERATOR_STATUS_SLASHED, op["status"].as()); - BOOST_REQUIRE_EQUAL(1u, slash_action_count(BATCHOP, ETH_OUTPOST_ID)); - BOOST_REQUIRE_EQUAL(1u, slash_action_count(BATCHOP, SOL_OUTPOST_ID)); - BOOST_REQUIRE_EQUAL(epoch + 1, current_epoch()); - BOOST_REQUIRE_EQUAL(2u, delivered_dellog_count(BATCHOP)); + BOOST_REQUIRE_EQUAL(kExpectedSlashActionsPerOutpost, + slash_action_count(BATCHOP, ETH_OUTPOST_ID)); + BOOST_REQUIRE_EQUAL(kExpectedSlashActionsPerOutpost, + slash_action_count(BATCHOP, SOL_OUTPOST_ID)); + BOOST_REQUIRE_EQUAL(epoch + kEpochAdvanceCount, current_epoch()); + BOOST_REQUIRE_EQUAL(kExpectedDeliveredLogCount, delivered_dellog_count(BATCHOP)); } FC_LOG_AND_RETHROW() } // SEC-28 (huang review): terminate on the CONSECUTIVE-miss rail through the REAL rotation -- a From e1b655eb071479d94163cf8b3eed6b1a36bab93c Mon Sep 17 00:00:00 2001 From: Huang-Ming Huang Date: Tue, 18 Aug 2026 20:17:37 +0000 Subject: [PATCH 11/17] Name WIRE-344 opreg test fields Change-Id: Id1b324ed568ba62d5caf912e64b12a45815c790f --- contracts/tests/sysio.msgch_chain_tests.cpp | 35 +++++++++++++++------ 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/contracts/tests/sysio.msgch_chain_tests.cpp b/contracts/tests/sysio.msgch_chain_tests.cpp index 2f3fc9afa5..646e0bfba2 100644 --- a/contracts/tests/sysio.msgch_chain_tests.cpp +++ b/contracts/tests/sysio.msgch_chain_tests.cpp @@ -63,6 +63,23 @@ constexpr std::string_view SOL_CHAIN_CODE = "SOL"; constexpr uint64_t BATCHOP_MIN_COLLATERAL = 1; constexpr uint64_t TABLE_SCAN_LIMIT = 64; +/// sysio.opreg action identifiers used by the WNS-16 fixture. +namespace opreg_actions { +constexpr name RECORD_DELIVERY = "recorddel"_n; +} // namespace opreg_actions + +/// sysio.opreg ABI field identifiers used by the WNS-16 fixture. +namespace opreg_fields { +constexpr const char* ACCOUNT = "account"; +constexpr const char* EPOCH = "epoch"; +constexpr const char* DELIVERED = "delivered"; +constexpr const char* RECENT_ACTIONS = "recent_actions"; +constexpr const char* ACTION = "action"; +constexpr const char* ACTION_TYPE = "action_type"; +constexpr const char* SUCCESS = "success"; +constexpr const char* CHAIN_CODE = "chain_code"; +} // namespace opreg_fields + } // anonymous namespace // --------------------------------------------------------------------------- @@ -305,10 +322,10 @@ class sysio_msgch_chain_tester : public tester { /// Seed a historical delivery outcome under epoch authority so the next /// real epoch advance exercises the rolling termination threshold. action_result record_delivery(name account, uint32_t epoch, bool delivered) { - return push(OPREG_ACCOUNT, opreg_abi, EPOCH_ACCOUNT, "recorddel"_n, mvo() - ("account", account.to_string()) - ("epoch", epoch) - ("delivered", delivered)); + return push(OPREG_ACCOUNT, opreg_abi, EPOCH_ACCOUNT, opreg_actions::RECORD_DELIVERY, mvo() + (opreg_fields::ACCOUNT, account.to_string()) + (opreg_fields::EPOCH, epoch) + (opreg_fields::DELIVERED, delivered)); } /// Let the consensus boundary elapse WITHOUT advancing the epoch: evalcons' fallback @@ -449,16 +466,16 @@ class sysio_msgch_chain_tester : public tester { using operator_action_type = sysio::opp::attestations::OperatorAction_ActionType; uint32_t n = 0; - for (const auto& log : op["recent_actions"].get_array()) { + for (const auto& log : op[opreg_fields::RECENT_ACTIONS].get_array()) { operator_action_type action_type = sysio::opp::attestations::OperatorAction_ActionType_ACTION_TYPE_UNKNOWN; - const auto& action = log["action"]; + const auto& action = log[opreg_fields::ACTION]; const bool is_slash = sysio::opp::attestations::OperatorAction_ActionType_Parse( - action["action_type"].as_string(), &action_type) && + action[opreg_fields::ACTION_TYPE].as_string(), &action_type) && action_type == sysio::opp::attestations::OperatorAction_ActionType_ACTION_TYPE_SLASH; - if (!log["success"].as_bool() || !is_slash || - action["chain_code"].as_uint64() != chain_code) continue; + if (!log[opreg_fields::SUCCESS].as_bool() || !is_slash || + action[opreg_fields::CHAIN_CODE].as_uint64() != chain_code) continue; ++n; } return n; From 448fd0ba19bf7416f7a607d3450e83ce3ff82a50 Mon Sep 17 00:00:00 2001 From: Huang-Ming Huang Date: Tue, 18 Aug 2026 20:36:18 +0000 Subject: [PATCH 12/17] Cover WIRE-344 cross-outpost slash deduplication Change-Id: I1a1c7f48e3b144bb6b722f8d19b93532d98d83d0 --- contracts/sysio.epoch/src/sysio.epoch.cpp | 10 ++++++++-- contracts/tests/sysio.msgch_chain_tests.cpp | 21 ++++++++++++++++----- 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/contracts/sysio.epoch/src/sysio.epoch.cpp b/contracts/sysio.epoch/src/sysio.epoch.cpp index 76cbd9f54a..cfa1d63807 100644 --- a/contracts/sysio.epoch/src/sysio.epoch.cpp +++ b/contracts/sysio.epoch/src/sysio.epoch.cpp @@ -50,6 +50,12 @@ namespace chalg_actions { constexpr name SLASHOP = "slashop"_n; } // namespace chalg_actions +/// Action identifiers owned by sysio.opreg and invoked while closing an epoch. +namespace opreg_actions { +constexpr name RECORD_DELIVERY = "recorddel"_n; +constexpr name TERMINATION_CHECK = "termcheck"_n; +} // namespace opreg_actions + /// Durable reason prefix for an epoch-delivery classification slash. constexpr const char* NON_CANONICAL_DELIVERY_REASON_PREFIX = "non-canonical OPP envelope delivery, epoch "; @@ -586,13 +592,13 @@ void epoch::advance() { action( permission_level{get_self(), "owner"_n}, OPREG_ACCOUNT, - "recorddel"_n, + opreg_actions::RECORD_DELIVERY, std::make_tuple(observation.member, state.current_epoch_index, observation.did_deliver) ).send(); action( permission_level{get_self(), "owner"_n}, OPREG_ACCOUNT, - "termcheck"_n, + opreg_actions::TERMINATION_CHECK, std::make_tuple(observation.member) ).send(); } diff --git a/contracts/tests/sysio.msgch_chain_tests.cpp b/contracts/tests/sysio.msgch_chain_tests.cpp index 646e0bfba2..59243c5080 100644 --- a/contracts/tests/sysio.msgch_chain_tests.cpp +++ b/contracts/tests/sysio.msgch_chain_tests.cpp @@ -1264,14 +1264,17 @@ BOOST_FIXTURE_TEST_CASE(noncanonical_delivery_slashes_before_termination, sysio_ const auto divergent_checksum = fc::sha256::hash(divergent.data(), divergent.size()); BOOST_REQUIRE_NE(canonical_checksum, divergent_checksum); - // Stage the split ETH deliveries and one SOL delivery before the boundary. - // The two remaining canonical deliveries reach majority after the boundary; - // then the permissionless chkcons crank advances the epoch inline. + // Stage the split deliveries for both outposts before the boundary. BATCHOP + // is non-canonical everywhere, so `advance` must deduplicate it before + // invoking slashop: a second opreg::slash throws and would roll the epoch + // advance back. BATCHOP_B/C establish canonical consensus after the boundary. BOOST_REQUIRE_EQUAL(success(), deliver_as(BATCHOP, ETH_OUTPOST_ID, divergent)); + BOOST_REQUIRE_EQUAL(success(), deliver_as(BATCHOP, SOL_OUTPOST_ID, divergent)); BOOST_REQUIRE_EQUAL(success(), deliver_as(BATCHOP_B, ETH_OUTPOST_ID, canonical)); - BOOST_REQUIRE_EQUAL(success(), deliver_as(BATCHOP, SOL_OUTPOST_ID, canonical)); + BOOST_REQUIRE_EQUAL(success(), deliver_as(BATCHOP_B, SOL_OUTPOST_ID, canonical)); elapse_epoch_boundary(); BOOST_REQUIRE_EQUAL(success(), deliver_as(BATCHOP_C, ETH_OUTPOST_ID, canonical)); + BOOST_REQUIRE_EQUAL(success(), deliver_as(BATCHOP_C, SOL_OUTPOST_ID, canonical)); { auto eth_consensus = get_outpcons(ETH_OUTPOST_ID); BOOST_REQUIRE(!eth_consensus.is_null()); @@ -1281,7 +1284,15 @@ BOOST_FIXTURE_TEST_CASE(noncanonical_delivery_slashes_before_termination, sysio_ BOOST_REQUIRE(!divergent_delivery.is_null()); BOOST_REQUIRE_EQUAL(divergent_checksum.str(), divergent_delivery["checksum"].as_string()); } - BOOST_REQUIRE_EQUAL(success(), deliver_as(BATCHOP_B, SOL_OUTPOST_ID, canonical)); + { + auto sol_consensus = get_outpcons(SOL_OUTPOST_ID); + BOOST_REQUIRE(!sol_consensus.is_null()); + BOOST_REQUIRE_EQUAL(epoch, sol_consensus["epoch_index"].as()); + BOOST_REQUIRE_EQUAL(canonical_checksum.str(), sol_consensus["winning_checksum"].as_string()); + auto divergent_delivery = find_inbound_delivery(SOL_OUTPOST_ID, epoch, BATCHOP); + BOOST_REQUIRE(!divergent_delivery.is_null()); + BOOST_REQUIRE_EQUAL(divergent_checksum.str(), divergent_delivery["checksum"].as_string()); + } BOOST_REQUIRE_EQUAL(success(), push(MSGCH_ACCOUNT, msgch_abi, MSGCH_ACCOUNT, "chkcons"_n, mvo())); produce_blocks(); From a321e43b5aa23b0cbeb87cb81774a69687cb794c Mon Sep 17 00:00:00 2001 From: Huang-Ming Huang Date: Tue, 18 Aug 2026 20:53:07 +0000 Subject: [PATCH 13/17] Name WIRE-344 msgch test identifiers Change-Id: I7daa38d9b8d4de069364eda4a02bebf513d330dc --- contracts/tests/sysio.msgch_chain_tests.cpp | 35 +++++++++++++++++---- 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/contracts/tests/sysio.msgch_chain_tests.cpp b/contracts/tests/sysio.msgch_chain_tests.cpp index 59243c5080..f2d7df28ee 100644 --- a/contracts/tests/sysio.msgch_chain_tests.cpp +++ b/contracts/tests/sysio.msgch_chain_tests.cpp @@ -80,6 +80,28 @@ constexpr const char* SUCCESS = "success"; constexpr const char* CHAIN_CODE = "chain_code"; } // namespace opreg_fields +/// sysio.msgch action identifiers used by the WNS-16 fixture. +namespace msgch_actions { +constexpr name CHECK_CONSENSUS = "chkcons"_n; +} // namespace msgch_actions + +/// sysio.msgch table identifiers used by the WNS-16 fixture. +namespace msgch_tables { +constexpr name ENVELOPES = "envelopes"_n; +} // namespace msgch_tables + +/// sysio.msgch ABI type identifiers used by the WNS-16 fixture. +namespace msgch_abi_types { +constexpr const char* ENVELOPE_ENTRY = "envelope_entry"; +} // namespace msgch_abi_types + +/// sysio.msgch ABI field identifiers used by the WNS-16 fixture. +namespace msgch_fields { +constexpr const char* CHAIN_CODE = "chain_code"; +constexpr const char* EPOCH_INDEX = "epoch_index"; +constexpr const char* BATCH_OP_NAME = "batch_op_name"; +} // namespace msgch_fields + } // anonymous namespace // --------------------------------------------------------------------------- @@ -379,13 +401,14 @@ class sysio_msgch_chain_tester : public tester { fc::variant find_inbound_delivery(uint64_t chain_code, uint32_t epoch_index, name batch_op, uint64_t scan_until = TABLE_SCAN_LIMIT) { for (uint64_t id = 0; id < scan_until; ++id) { - auto data = get_row_by_id(MSGCH_ACCOUNT, MSGCH_ACCOUNT, "envelopes"_n, id); + auto data = get_row_by_id(MSGCH_ACCOUNT, MSGCH_ACCOUNT, msgch_tables::ENVELOPES, id); if (data.empty()) continue; auto row = msgch_abi.binary_to_variant( - "envelope_entry", data, abi_serializer::create_yield_function(abi_serializer_max_time)); - if (row["chain_code"].as_uint64() == chain_code && - row["epoch_index"].as() == epoch_index && - row["batch_op_name"].as_string() == batch_op.to_string()) return row; + msgch_abi_types::ENVELOPE_ENTRY, data, + abi_serializer::create_yield_function(abi_serializer_max_time)); + if (row[msgch_fields::CHAIN_CODE].as_uint64() == chain_code && + row[msgch_fields::EPOCH_INDEX].as() == epoch_index && + row[msgch_fields::BATCH_OP_NAME].as_string() == batch_op.to_string()) return row; } return fc::variant{}; } @@ -1294,7 +1317,7 @@ BOOST_FIXTURE_TEST_CASE(noncanonical_delivery_slashes_before_termination, sysio_ BOOST_REQUIRE_EQUAL(divergent_checksum.str(), divergent_delivery["checksum"].as_string()); } BOOST_REQUIRE_EQUAL(success(), push(MSGCH_ACCOUNT, msgch_abi, MSGCH_ACCOUNT, - "chkcons"_n, mvo())); + msgch_actions::CHECK_CONSENSUS, mvo())); produce_blocks(); auto op = get_operator(BATCHOP); From a4d78e42a6dcfe03741eb6fe9da0a6c82fd65b05 Mon Sep 17 00:00:00 2001 From: Huang-Ming Huang Date: Tue, 18 Aug 2026 21:08:09 +0000 Subject: [PATCH 14/17] Use typed enum conversions in epoch scheduling Change-Id: I0cb61b2bc6176044fd77a71652607219003e0f4b --- contracts/sysio.epoch/src/sysio.epoch.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/contracts/sysio.epoch/src/sysio.epoch.cpp b/contracts/sysio.epoch/src/sysio.epoch.cpp index cfa1d63807..7d7e395a4c 100644 --- a/contracts/sysio.epoch/src/sysio.epoch.cpp +++ b/contracts/sysio.epoch/src/sysio.epoch.cpp @@ -18,6 +18,7 @@ #include #include #include +#include namespace sysio { @@ -656,7 +657,7 @@ void epoch::advance() { auto status_idx = opreg_ops.get_index<"bystatus"_n>(); std::vector> pool; for (auto it = status_idx.lower_bound( - static_cast(OperatorStatus::OPERATOR_STATUS_ACTIVE)); + magic_enum::enum_integer(OperatorStatus::OPERATOR_STATUS_ACTIVE)); it != status_idx.end() && it->status == OperatorStatus::OPERATOR_STATUS_ACTIVE; ++it) { if (it->type == OperatorType::OPERATOR_TYPE_BATCH && !is_resident(it->account)) { @@ -736,7 +737,7 @@ void epoch::advance() { auto link_it = links_by_name.lower_bound(it->account.value); while (link_it != links_by_name.end() && link_it->username == it->account) { opp::types::ChainAddress chain_addr; - chain_addr.kind = static_cast(link_it->chain_kind); + chain_addr.kind = link_it->chain_kind; std::visit([&](const auto& key_data) { using T = std::decay_t; @@ -920,7 +921,7 @@ void epoch::schbatchgps() { auto status_idx = opreg_ops.get_index<"bystatus"_n>(); std::vector> available_batch; // (account, is_bootstrapped) for (auto it = status_idx.lower_bound( - static_cast(OperatorStatus::OPERATOR_STATUS_ACTIVE)); + magic_enum::enum_integer(OperatorStatus::OPERATOR_STATUS_ACTIVE)); it != status_idx.end() && it->status == OperatorStatus::OPERATOR_STATUS_ACTIVE; ++it) { if (it->type == OperatorType::OPERATOR_TYPE_BATCH) { From f587baba195232544456b3f0b79ad8bffaa774c7 Mon Sep 17 00:00:00 2001 From: Huang-Ming Huang Date: Tue, 18 Aug 2026 21:25:40 +0000 Subject: [PATCH 15/17] Name WIRE-344 assertion ABI fields Change-Id: Ie34d67981a0c1e17e7ddc9d724306cc2af01dcea --- contracts/tests/sysio.msgch_chain_tests.cpp | 196 ++++++++++++++------ 1 file changed, 141 insertions(+), 55 deletions(-) diff --git a/contracts/tests/sysio.msgch_chain_tests.cpp b/contracts/tests/sysio.msgch_chain_tests.cpp index f2d7df28ee..f542870a5b 100644 --- a/contracts/tests/sysio.msgch_chain_tests.cpp +++ b/contracts/tests/sysio.msgch_chain_tests.cpp @@ -60,19 +60,17 @@ constexpr uint64_t ETH_OUTPOST_ID = "ETH"_s.value; constexpr uint64_t SOL_OUTPOST_ID = "SOL"_s.value; constexpr std::string_view ETH_CHAIN_CODE = "ETH"; constexpr std::string_view SOL_CHAIN_CODE = "SOL"; -constexpr uint64_t BATCHOP_MIN_COLLATERAL = 1; +constexpr uint64_t BATCH_OPERATOR_MINIMUM_COLLATERAL = 1; constexpr uint64_t TABLE_SCAN_LIMIT = 64; /// sysio.opreg action identifiers used by the WNS-16 fixture. namespace opreg_actions { -constexpr name RECORD_DELIVERY = "recorddel"_n; +constexpr name SET_CONFIG = "setconfig"_n; } // namespace opreg_actions /// sysio.opreg ABI field identifiers used by the WNS-16 fixture. namespace opreg_fields { -constexpr const char* ACCOUNT = "account"; -constexpr const char* EPOCH = "epoch"; -constexpr const char* DELIVERED = "delivered"; +constexpr const char* STATUS = "status"; constexpr const char* RECENT_ACTIONS = "recent_actions"; constexpr const char* ACTION = "action"; constexpr const char* ACTION_TYPE = "action_type"; @@ -80,6 +78,20 @@ constexpr const char* SUCCESS = "success"; constexpr const char* CHAIN_CODE = "chain_code"; } // namespace opreg_fields +/// sysio.opreg configuration ABI field identifiers used by the WNS-16 fixture. +namespace opreg_config_fields { +constexpr const char* MAX_AVAILABLE_PRODUCERS = "max_available_producers"; +constexpr const char* MAX_AVAILABLE_BATCH_OPERATORS = "max_available_batch_ops"; +constexpr const char* MAX_AVAILABLE_UNDERWRITERS = "max_available_underwriters"; +constexpr const char* TERMINATE_PRUNE_DELAY_MS = "terminate_prune_delay_ms"; +constexpr const char* TERMINATE_MAX_CONSECUTIVE_MISSES = "terminate_max_consecutive_misses"; +constexpr const char* TERMINATE_MAX_PERCENT_MISSES_24H = "terminate_max_pct_misses_24h"; +constexpr const char* TERMINATE_WINDOW_MS = "terminate_window_ms"; +constexpr const char* REQUIRED_PRODUCER_COLLATERAL = "req_prod_collat"; +constexpr const char* REQUIRED_BATCH_OPERATOR_COLLATERAL = "req_batchop_collat"; +constexpr const char* REQUIRED_UNDERWRITER_COLLATERAL = "req_uw_collat"; +} // namespace opreg_config_fields + /// sysio.msgch action identifiers used by the WNS-16 fixture. namespace msgch_actions { constexpr name CHECK_CONSENSUS = "chkcons"_n; @@ -100,8 +112,16 @@ namespace msgch_fields { constexpr const char* CHAIN_CODE = "chain_code"; constexpr const char* EPOCH_INDEX = "epoch_index"; constexpr const char* BATCH_OP_NAME = "batch_op_name"; +constexpr const char* WINNING_CHECKSUM = "winning_checksum"; +constexpr const char* CHECKSUM = "checksum"; } // namespace msgch_fields +/// sysio.epoch ABI field identifiers used by the WNS-16 fixture. +namespace epoch_fields { +constexpr const char* BATCH_OP_GROUPS = "batch_op_groups"; +constexpr const char* CURRENT_BATCH_OP_GROUP = "current_batch_op_group"; +} // namespace epoch_fields + } // anonymous namespace // --------------------------------------------------------------------------- @@ -259,9 +279,9 @@ class sysio_msgch_chain_tester : public tester { ? fc::variants{} : fc::variants{ make_chain_min_bond(ETH_CHAIN_CODE, ETH_CHAIN_CODE, - BATCHOP_MIN_COLLATERAL), + BATCH_OPERATOR_MINIMUM_COLLATERAL), make_chain_min_bond(SOL_CHAIN_CODE, SOL_CHAIN_CODE, - BATCHOP_MIN_COLLATERAL) }) + BATCH_OPERATOR_MINIMUM_COLLATERAL) }) ("req_uw_collat", fc::variants{}))); std::vector batch_ops{BATCHOP}; @@ -284,9 +304,9 @@ class sysio_msgch_chain_tester : public tester { // only after a collateral update re-evaluates its role eligibility. if (!batchop_is_bootstrapped) { BOOST_REQUIRE_EQUAL(success(), depositinle(BATCHOP, ETH_CHAIN_CODE, ETH_CHAIN_CODE, - BATCHOP_MIN_COLLATERAL)); + BATCH_OPERATOR_MINIMUM_COLLATERAL)); BOOST_REQUIRE_EQUAL(success(), depositinle(BATCHOP, SOL_CHAIN_CODE, SOL_CHAIN_CODE, - BATCHOP_MIN_COLLATERAL, + BATCH_OPERATOR_MINIMUM_COLLATERAL, opp::types::ChainKind::CHAIN_KIND_SVM)); } @@ -341,15 +361,6 @@ class sysio_msgch_chain_tester : public tester { ("data", data)); } - /// Seed a historical delivery outcome under epoch authority so the next - /// real epoch advance exercises the rolling termination threshold. - action_result record_delivery(name account, uint32_t epoch, bool delivered) { - return push(OPREG_ACCOUNT, opreg_abi, EPOCH_ACCOUNT, opreg_actions::RECORD_DELIVERY, mvo() - (opreg_fields::ACCOUNT, account.to_string()) - (opreg_fields::EPOCH, epoch) - (opreg_fields::DELIVERED, delivered)); - } - /// Let the consensus boundary elapse WITHOUT advancing the epoch: evalcons' fallback /// (majority) path opens once `epoch_duration_sec` has passed since the epoch started, /// while `deliver`'s epoch gate keeps accepting envelopes for the still-current epoch. @@ -562,6 +573,40 @@ class sysio_msgch_chain_tester : public tester { ("config_timestamp_ms", uint64_t{0})); } + /// Reconfigure only the rolling-termination rails while preserving the WNS-16 fixture's + /// collateral requirements. This lets the test build real history under a permissive policy, + /// then demonstrate that deferred slashing wins when the same history becomes terminating. + void set_termination_thresholds(uint32_t max_consecutive_misses, uint32_t max_percent_misses) { + constexpr uint32_t MAX_AVAILABLE_PRODUCERS = 21; + constexpr uint32_t MAX_AVAILABLE_BATCH_OPERATORS = 63; + constexpr uint32_t MAX_AVAILABLE_UNDERWRITERS = 21; + constexpr uint64_t TERMINATE_PRUNE_DELAY_MS = 600'000; + constexpr uint64_t TERMINATE_WINDOW_MS = 24ULL * 60 * 60 * 1000; + + BOOST_REQUIRE_EQUAL(success(), push(OPREG_ACCOUNT, opreg_abi, OPREG_ACCOUNT, + opreg_actions::SET_CONFIG, mvo() + (opreg_config_fields::MAX_AVAILABLE_PRODUCERS, MAX_AVAILABLE_PRODUCERS) + (opreg_config_fields::MAX_AVAILABLE_BATCH_OPERATORS, MAX_AVAILABLE_BATCH_OPERATORS) + (opreg_config_fields::MAX_AVAILABLE_UNDERWRITERS, MAX_AVAILABLE_UNDERWRITERS) + (opreg_config_fields::TERMINATE_PRUNE_DELAY_MS, TERMINATE_PRUNE_DELAY_MS) + (opreg_config_fields::TERMINATE_MAX_CONSECUTIVE_MISSES, max_consecutive_misses) + (opreg_config_fields::TERMINATE_MAX_PERCENT_MISSES_24H, max_percent_misses) + (opreg_config_fields::TERMINATE_WINDOW_MS, TERMINATE_WINDOW_MS) + (opreg_config_fields::REQUIRED_PRODUCER_COLLATERAL, fc::variants{}) + (opreg_config_fields::REQUIRED_BATCH_OPERATOR_COLLATERAL, fc::variants{ + make_chain_min_bond(ETH_CHAIN_CODE, ETH_CHAIN_CODE, BATCH_OPERATOR_MINIMUM_COLLATERAL), + make_chain_min_bond(SOL_CHAIN_CODE, SOL_CHAIN_CODE, BATCH_OPERATOR_MINIMUM_COLLATERAL) }) + (opreg_config_fields::REQUIRED_UNDERWRITER_COLLATERAL, fc::variants{}))); + } + + /// Once every active outpost has a durable consensus row for the current epoch, trigger the + /// production `chkcons -> advance` route that records delivery history and evaluates termination. + void advance_via_consensus() { + BOOST_REQUIRE_EQUAL(success(), push(MSGCH_ACCOUNT, msgch_abi, MSGCH_ACCOUNT, + msgch_actions::CHECK_CONSENSUS, mvo())); + produce_blocks(); + } + /// Inline collateral credit (the path sysio.msgch drives in production; pushed directly here) that /// lifts a non-bootstrapped operator to ACTIVE once its bond meets the configured minimum. action_result depositinle(name account, std::string_view chain_code, std::string_view token_code, @@ -1240,29 +1285,35 @@ BOOST_FIXTURE_TEST_CASE(late_confirmation_after_consensus_recorded, sysio_msgch_ } FC_LOG_AND_RETHROW() } /// WNS-16: a non-canonical delivery must be slashed before its historical -/// miss window can terminate it. The last canonical delivery reaches -/// consensus for both outposts and drives the real `chkcons -> advance` -/// path; pre-fix, `termcheck` marked BATCHOP TERMINATED before `slashop` -/// rejected that state and rolled the entire epoch back. +/// miss window can terminate it. The fixture builds its historical anchor and +/// miss through real `chkcons -> advance` transitions, then lowers the +/// consecutive-miss threshold before the divergent epoch. Pre-fix, `termcheck` +/// marked BATCHOP TERMINATED before `slashop` rejected that state and rolled +/// the entire epoch back. BOOST_FIXTURE_TEST_CASE(noncanonical_delivery_slashes_before_termination, sysio_msgch_chain_tester) { try { - constexpr uint32_t kBatchOperatorCount = 3; - constexpr uint32_t kExpectedInitialEpoch = 1; - constexpr uint32_t kMaxConsecutiveMisses = 5; - constexpr uint32_t kHistoricalMissesPastTerminationThreshold = 1; - constexpr const char* kCanonicalPayload = "canonical"; - constexpr const char* kNonCanonicalPayload = "non-canonical"; - constexpr uint32_t kExpectedSlashActionsPerOutpost = 1; - constexpr uint32_t kEpochAdvanceCount = 1; - constexpr uint32_t kExpectedDeliveredLogCount = 2; + constexpr uint32_t kBatchOperatorCount = 3; + constexpr uint32_t kExpectedInitialEpoch = 1; + constexpr uint32_t kPermissiveMaxConsecutiveMisses = 5; + constexpr uint32_t kPermissiveMaxPercentMisses = 99; + constexpr uint32_t kTerminatingMaxConsecutiveMisses = 1; + constexpr const char* kHistoricalAnchorPayload = "history-anchor"; + constexpr const char* kHistoricalMissPayload = "history-miss"; + constexpr const char* kCanonicalPayload = "canonical"; + constexpr const char* kNonCanonicalPayload = "non-canonical"; + constexpr uint32_t kExpectedSlashActionsPerOutpost = 1; + constexpr uint32_t kEpochAdvanceCount = 1; + constexpr uint32_t kExpectedDeliveredLogCount = 4; bootstrap(/*n_batch_ops=*/kBatchOperatorCount, /*batchop_is_bootstrapped=*/false); BOOST_REQUIRE_EQUAL(kExpectedInitialEpoch, current_epoch()); BOOST_REQUIRE_EQUAL(opp::types::OperatorStatus::OPERATOR_STATUS_ACTIVE, - get_operator(BATCHOP)["status"].as()); + get_operator(BATCHOP)[opreg_fields::STATUS] + .as()); { auto state = read_epoch_state(); - auto groups = state["batch_op_groups"].get_array(); - auto active_group = groups[state["current_batch_op_group"].as_uint64()].get_array(); + auto groups = state[epoch_fields::BATCH_OP_GROUPS].get_array(); + auto active_group = + groups[state[epoch_fields::CURRENT_BATCH_OP_GROUP].as_uint64()].get_array(); bool batchop_is_scheduled = false; for (const auto& member : active_group) { if (member.as_string() == BATCHOP.to_string()) batchop_is_scheduled = true; @@ -1270,19 +1321,52 @@ BOOST_FIXTURE_TEST_CASE(noncanonical_delivery_slashes_before_termination, sysio_ BOOST_REQUIRE(batchop_is_scheduled); } - // Seed enough prior misses for the next termcheck to terminate BATCHOP if - // it remains ACTIVE. The current epoch's non-canonical delivery still - // counts as delivered, so this specifically covers the ordering conflict. - for (uint32_t prior_epoch = kExpectedInitialEpoch; - prior_epoch <= kMaxConsecutiveMisses + kHistoricalMissesPastTerminationThreshold; - ++prior_epoch) { - BOOST_REQUIRE_EQUAL(success(), record_delivery(BATCHOP, prior_epoch, /*delivered=*/false)); - produce_blocks(); - } + // Create reachable history under permissive rails. The first epoch's canonical anchor prevents + // the 99% percent rail from terminating BATCHOP while the next epoch records two real misses + // (one per active outpost) through advance()'s inline recorddel/termcheck calls. + set_termination_thresholds(kPermissiveMaxConsecutiveMisses, kPermissiveMaxPercentMisses); + const uint32_t anchor_epoch = current_epoch(); + const auto historical_anchor = encode_delivery(anchor_epoch, kHistoricalAnchorPayload); + const auto historical_anchor_digest = oracle::epoch_digest(decode_envelope(historical_anchor)); + const auto historical_anchor_message_id = delivery_message_id(historical_anchor); + BOOST_REQUIRE_EQUAL(success(), deliver_as(BATCHOP, ETH_OUTPOST_ID, historical_anchor)); + BOOST_REQUIRE_EQUAL(success(), deliver_as(BATCHOP, SOL_OUTPOST_ID, historical_anchor)); + BOOST_REQUIRE_EQUAL(success(), deliver_as(BATCHOP_B, ETH_OUTPOST_ID, historical_anchor)); + BOOST_REQUIRE_EQUAL(success(), deliver_as(BATCHOP_B, SOL_OUTPOST_ID, historical_anchor)); + elapse_epoch_boundary(); + BOOST_REQUIRE_EQUAL(success(), deliver_as(BATCHOP_C, ETH_OUTPOST_ID, historical_anchor)); + BOOST_REQUIRE_EQUAL(success(), deliver_as(BATCHOP_C, SOL_OUTPOST_ID, historical_anchor)); + advance_via_consensus(); + BOOST_REQUIRE_EQUAL(anchor_epoch + kEpochAdvanceCount, current_epoch()); + + const uint32_t missed_epoch = current_epoch(); + const auto historical_miss = encode_delivery( + missed_epoch, kHistoricalMissPayload, + oracle::digest_bytes(historical_anchor_digest), historical_anchor_message_id); + const auto historical_miss_digest = oracle::epoch_digest(decode_envelope(historical_miss)); + const auto historical_miss_message_id = delivery_message_id(historical_miss); + BOOST_REQUIRE_EQUAL(success(), deliver_as(BATCHOP_B, ETH_OUTPOST_ID, historical_miss)); + BOOST_REQUIRE_EQUAL(success(), deliver_as(BATCHOP_B, SOL_OUTPOST_ID, historical_miss)); + elapse_epoch_boundary(); + BOOST_REQUIRE_EQUAL(success(), deliver_as(BATCHOP_C, ETH_OUTPOST_ID, historical_miss)); + BOOST_REQUIRE_EQUAL(success(), deliver_as(BATCHOP_C, SOL_OUTPOST_ID, historical_miss)); + advance_via_consensus(); + BOOST_REQUIRE_EQUAL(missed_epoch + kEpochAdvanceCount, current_epoch()); + BOOST_REQUIRE_EQUAL(opp::types::OperatorStatus::OPERATOR_STATUS_ACTIVE, + get_operator(BATCHOP)[opreg_fields::STATUS] + .as()); + + // The accumulated real misses are now terminating. A non-canonical delivery is still recorded + // as delivered, so only slash-first ordering prevents termcheck from blocking this advance. + set_termination_thresholds(kTerminatingMaxConsecutiveMisses, kPermissiveMaxPercentMisses); const uint32_t epoch = current_epoch(); - const auto canonical = encode_delivery(epoch, kCanonicalPayload); - const auto divergent = encode_delivery(epoch, kNonCanonicalPayload); + const auto canonical = encode_delivery( + epoch, kCanonicalPayload, + oracle::digest_bytes(historical_miss_digest), historical_miss_message_id); + const auto divergent = encode_delivery( + epoch, kNonCanonicalPayload, + oracle::digest_bytes(historical_miss_digest), historical_miss_message_id); const auto canonical_checksum = fc::sha256::hash(canonical.data(), canonical.size()); const auto divergent_checksum = fc::sha256::hash(divergent.data(), divergent.size()); BOOST_REQUIRE_NE(canonical_checksum, divergent_checksum); @@ -1301,28 +1385,30 @@ BOOST_FIXTURE_TEST_CASE(noncanonical_delivery_slashes_before_termination, sysio_ { auto eth_consensus = get_outpcons(ETH_OUTPOST_ID); BOOST_REQUIRE(!eth_consensus.is_null()); - BOOST_REQUIRE_EQUAL(epoch, eth_consensus["epoch_index"].as()); - BOOST_REQUIRE_EQUAL(canonical_checksum.str(), eth_consensus["winning_checksum"].as_string()); + BOOST_REQUIRE_EQUAL(epoch, eth_consensus[msgch_fields::EPOCH_INDEX].as()); + BOOST_REQUIRE_EQUAL(canonical_checksum.str(), + eth_consensus[msgch_fields::WINNING_CHECKSUM].as_string()); auto divergent_delivery = find_inbound_delivery(ETH_OUTPOST_ID, epoch, BATCHOP); BOOST_REQUIRE(!divergent_delivery.is_null()); - BOOST_REQUIRE_EQUAL(divergent_checksum.str(), divergent_delivery["checksum"].as_string()); + BOOST_REQUIRE_EQUAL(divergent_checksum.str(), + divergent_delivery[msgch_fields::CHECKSUM].as_string()); } { auto sol_consensus = get_outpcons(SOL_OUTPOST_ID); BOOST_REQUIRE(!sol_consensus.is_null()); - BOOST_REQUIRE_EQUAL(epoch, sol_consensus["epoch_index"].as()); - BOOST_REQUIRE_EQUAL(canonical_checksum.str(), sol_consensus["winning_checksum"].as_string()); + BOOST_REQUIRE_EQUAL(epoch, sol_consensus[msgch_fields::EPOCH_INDEX].as()); + BOOST_REQUIRE_EQUAL(canonical_checksum.str(), + sol_consensus[msgch_fields::WINNING_CHECKSUM].as_string()); auto divergent_delivery = find_inbound_delivery(SOL_OUTPOST_ID, epoch, BATCHOP); BOOST_REQUIRE(!divergent_delivery.is_null()); - BOOST_REQUIRE_EQUAL(divergent_checksum.str(), divergent_delivery["checksum"].as_string()); + BOOST_REQUIRE_EQUAL(divergent_checksum.str(), + divergent_delivery[msgch_fields::CHECKSUM].as_string()); } - BOOST_REQUIRE_EQUAL(success(), push(MSGCH_ACCOUNT, msgch_abi, MSGCH_ACCOUNT, - msgch_actions::CHECK_CONSENSUS, mvo())); - produce_blocks(); + advance_via_consensus(); auto op = get_operator(BATCHOP); BOOST_REQUIRE_EQUAL(opp::types::OperatorStatus::OPERATOR_STATUS_SLASHED, - op["status"].as()); + op[opreg_fields::STATUS].as()); BOOST_REQUIRE_EQUAL(kExpectedSlashActionsPerOutpost, slash_action_count(BATCHOP, ETH_OUTPOST_ID)); BOOST_REQUIRE_EQUAL(kExpectedSlashActionsPerOutpost, From f9c7e1c8180cc40540f72b00adbf49b6f863c383 Mon Sep 17 00:00:00 2001 From: Huang-Ming Huang Date: Wed, 19 Aug 2026 00:26:06 +0000 Subject: [PATCH 16/17] Sync WIRE-344 epoch contract artifact Change-Id: Ie84885038d04ef10ae74aef1997fa2702aa3e4f6 --- contracts/sysio.epoch/sysio.epoch.wasm | Bin 75700 -> 92372 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/contracts/sysio.epoch/sysio.epoch.wasm b/contracts/sysio.epoch/sysio.epoch.wasm index 61f97c5bc96ed37cd4628813ec4e821e347f151b..f6852065c1daca74cac990e33c17afcc8295d5e3 100755 GIT binary patch literal 92372 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 YQ%JWX-GTIJq|YE>sLxHkd$(cy4+B=4YybcN literal 75700 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 b@HOxa@GbBi@ICMY@FReq1=sk`NYDEp<@rDn From 737e0cb6f6168fd72722696fe58ea9d5c880a009 Mon Sep 17 00:00:00 2001 From: Huang-Ming Huang Date: Wed, 19 Aug 2026 13:47:43 +0000 Subject: [PATCH 17/17] Address WIRE-344 review feedback Change-Id: Iaff848a24819393707e3e9c4c4d694cacfe3c9f6 --- contracts/sysio.epoch/src/sysio.epoch.cpp | 18 ++++++++---------- contracts/sysio.epoch/sysio.epoch.wasm | Bin 92372 -> 76069 bytes 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/contracts/sysio.epoch/src/sysio.epoch.cpp b/contracts/sysio.epoch/src/sysio.epoch.cpp index 7d7e395a4c..ca1c2ed089 100644 --- a/contracts/sysio.epoch/src/sysio.epoch.cpp +++ b/contracts/sysio.epoch/src/sysio.epoch.cpp @@ -565,16 +565,14 @@ void epoch::advance() { // operator is marked SLASHED. // // Invariant — no cross-epoch double slash: opreg::slash THROWS on an already-SLASHED operator, - // which would abort advance and stall OPP epoch advancement. A slashed operator is guaranteed - // never to reappear in a later expiring group, so advance never attempts a second slash of it: - // 1. this flush runs BEFORE the window-slide below, so the operator is already SLASHED when - // the next tail group is formed; - // 2. the new-tail filter pulls OPERATOR_STATUS_ACTIVE operators only (see the schedule slide - // below), so a SLASHED operator is excluded from every newly-formed group; and - // 3. resident-exclusion keeps an operator in at most one group within the window, so the - // operator slashed for THIS (expiring) group is not also sitting in a future - // already-scheduled group. - // If any of those three scheduling facts change, this single-slash path must be revisited. + // which would abort advance and stall OPP epoch advancement. These inline slashes execute only + // after advance returns, so the schedule slide below can temporarily place a just-slashed + // operator in its new tail while the operator still reads ACTIVE. That member cannot create a + // later non-canonical observation: sysio.msgch::deliver requires its current sysio.opreg status + // to be ACTIVE before accepting delivery. Once the slash has executed, the scheduled SLASHED + // member cannot deliver or be queued for another non-canonical-delivery slash. The collection + // above also deduplicates multiple non-canonical observations for one member in this advance. + // Keep the deliver status gate and this single-slash path in sync if either behavior changes. for (const auto& member : to_slash) { action( permission_level{get_self(), "owner"_n}, diff --git a/contracts/sysio.epoch/sysio.epoch.wasm b/contracts/sysio.epoch/sysio.epoch.wasm index f6852065c1daca74cac990e33c17afcc8295d5e3..b6a25dca52c14194317677d8cfec1895464b4e65 100755 GIT binary patch literal 76069 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

Xe&h5d2wetGx7*`43Z-~M`d z`_a9#`{kc^?|At5z90CZANjGL_^F@yxnBf+5CmZm1#yrBX^;hZP=tOMgkczkahQZ@ zn1y**M1B-RVH8DiltgKiMR`=jejLPM9K~^*#A%$xd0ZrZ5+q>~C2^7@X_6&*Qlx$w zq+uGRahjxQnx%PKWPTQ8VHRa^mSky`WqDTQejemu9_4YKX+XIot#ZAyG8r+t@F^~wkC0Su48T}cye3)E+&_a|bFZEJ+!(SnBX^Sxo%gI;56Im=geD4A=mcBGMu%PC={B&K(8URa=Z@Ag0cdZ+*0Fia2fkPA!J zqM77^ckGiyc)jHy-=PPNYR?A)l1jGYflgxJ)Ith9{(MO9&7wZdO)7?kjab3n(}Y}24_hmzFL=?8SsbYI zY&vtyReQHsKbQ?p2Zkn4*W2;11hpN95Kb^o9622-+#XDR0`7<-)zEAh-y%AH5ryeQ zaP}09bnTh-Wd;VDHM`!-npMn0556ly7@UD3UcoldJcpZ2HcoVn*yal`soB*f5JHPYMW0|R((6|3JX~q*lwy!>I{Oc|ghYX&X6|k29(gx|Fp3kts%ly{ z8}avf+ey_w*2WIo-G00Psl(@8T;BuU2R;Bk1didh9A|@@K6m!x{zt&az$d_`z-Pec Zz!$)mz*oT6z&F6R0Dcyn;y)uj?|%S{zhM9X literal 92372 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 YQ%JWX-GTIJq|YE>sLxHkd$(cy4+B=4YybcN