Skip to content

[WNS-15 follow-up] fix: cover two-candidate dispute slashing - #83

Closed
huangminghuang wants to merge 28 commits into
masterfrom
fix/wire-362-two-candidate-slashing-flow-platform
Closed

huangminghuang wants to merge 28 commits into
masterfrom
fix/wire-362-two-candidate-slashing-flow-platform

Conversation

@huangminghuang

@huangminghuang huangminghuang commented Aug 21, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • Adds flow-batch-operator-terminal-tie, which keeps three configured operator seats, terminates one scheduled operator, and proves that the two remaining eligible operators open and resolve a two-candidate dispute with one non-canonical slash.
  • Preserves flow-batch-operator-slashing as the three-operator, three-candidate regression that produces two slashes.
  • Keeps reusable dispute orchestration in the private @wireio/batch-operator-dispute-shared support package while each flow owns its concrete scenario; no scenario lives in cluster-tool and no flow depends on another flow.
  • Adds typed chalg::votedispute, msgch::deliver, and opreg::processbatch planning/runners, while retaining the generic envelope codec, inbound-tip reader, and single-flight cache in cluster-tool.
  • Uses the SDK node-owner registration type with eth_address, constrains scenario participants to the provisioned operator roster, and rejects invalid or duplicate topology inputs during planning.
  • Incorporates current master, including the repository-wide Immer 11.2.8 resolution, and documents the private dispute-support package boundary in the package inventory.

Why

The dispute candidate threshold must come from the live eligible operator set, not the configured epoch group size. This flow keeps operators_per_epoch at three, administratively terminates one scheduled operator, and verifies that the resulting two live deliverers form the candidate set that opens the dispute.

The two dispute flows share substantial orchestration but remain independent executables. A private support package provides that shared behavior without putting flow scenarios in the generic cluster library, creating flow-to-flow coupling, or executing a flow as an import side effect. The package is named batch-operator-dispute-shared to make that support-only boundary explicit; the rename did not alter its runtime source or tests.

Validation

  • @wireio/batch-operator-dispute-shared and both concrete flow unit suites passed: 21/21 tests.
  • @wireio/cluster-tool-shared passed 22 suites / 249 tests, and @wireio/cluster-tool passed 169 suites / 2,348 tests.
  • Fresh dependency installation, root TypeScript build, focused cluster builds, lint, hygiene, and git diff --check passed against merged master d28e094dfa73b9fcad7b0dd1f65e4353ebb411cb.
  • Refreshed independent reviews passed with no PR-scoped findings: architecture 98/100, compliance 98/100, correctness 98/100, and publication/style 98/100.
  • Coordinated full E2E run 39847691895 passed all 15 discovered flows, including both WIRE-362 flows and syndication-plugin-underwriting; only the standard flow-swap-epoch-stress exclusion was omitted. The verified stack used Tools d4c26fa719b396291a522b2a901d2f0f95e5a68d, Sysio 97731f20f26ab0c781cd8d77b884ac8f8f9efe8d, Ethereum 0b5184cec04cb8268c5d95331cfc1fb922173eac, Solana 73f69330a7eff416aa139e423c3124aee2b094e5, and coordinator 3899d2cbd9c4655402874aa6e638bc3c01609187. The subsequent Tools commit only renames the private support package and its references; the moved runtime source and tests are byte-identical.
  • The preceding run passed both WIRE-362 flows and 14/15 overall; its unrelated underwriting timeout matched an existing timing-sensitive transition from busy cranking to the five-minute idle cadence and did not reproduce in the green run above.

Change-Id: I4e754b569c729378751a182f29eb1093387c9f80
…tform

Change-Id: I8a1498a59d3f6d41b164ee7bc89ff8ab16def7c9
@huangminghuang
huangminghuang marked this pull request as ready for review August 22, 2026 14:57
…ndidate-slashing-flow-platform

Change-Id: I86ef108e0842924d5f3bae6133c39caf04acc846
Change-Id: Ia1741dcf76e25ca3a7ec6351fa3128fd8755a710
@huangminghuang
huangminghuang requested a review from heifner August 28, 2026 14:42
@huangminghuang
huangminghuang marked this pull request as draft September 23, 2026 21:43
…ndidate-slashing-flow-platform

# Conflicts:
#	jest.config.ts
#	package.json
#	packages/cluster-tool-shared/package.json
#	packages/cluster-tool/package.json
#	packages/cluster-tool/src/flow/index.ts
#	packages/cluster-tool/src/orchestration/steps/contracts/sysio/OpregContractSteps.ts
#	packages/cluster-tool/tests/orchestration/steps/contracts/sysio/OpregContractSteps.test.ts
#	packages/debugging-client-shared/package.json
#	packages/debugging-client-tool-tui/package.json
#	packages/debugging-client-tool/package.json
#	packages/debugging-server/package.json
#	packages/flow-batch-operator-slashing/package.json
#	packages/flow-batch-operator-termination/package.json
#	packages/flow-emissions-soak/package.json
#	packages/flow-node-owner-nft/package.json
#	packages/flow-operator-collateral-deposit/package.json
#	packages/flow-producer-registration/package.json
#	packages/flow-reserve-lifecycle/package.json
#	packages/flow-swap-from-wire/package.json
#	packages/flow-swap-non-native-tokens/package.json
#	packages/flow-swap-private-reserves/package.json
#	packages/flow-swap-to-wire/package.json
#	packages/flow-swap-variance-revert/package.json
#	packages/flow-swap-with-underwriting/package.json
#	packages/flow-underwriter-slashing/package.json
#	packages/flow-yield-distribution/package.json
#	packages/test-app-server/package.json
#	tsconfig.json
@huangminghuang huangminghuang changed the title fix: cover two-candidate dispute slashing [WNS-15 follow-up] fix: cover two-candidate dispute slashing Oct 21, 2026
@huangminghuang
huangminghuang marked this pull request as ready for review October 21, 2026 17:34

@jglanz jglanz left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@heifner there are some wild missteps, did you run your session from wire-platform?

The changes need to be addressed

@@ -0,0 +1,11 @@
import "source-map-support/register"

import { BatchOperatorTerminalTieScenario, FlowCLI } from "@wireio/cluster-tool"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No scenario should be in the cluster-tool package

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 1ef40742. The terminal-tie entry point now instantiates the concrete scenario owned by its flow package; cluster-tool no longer exports or owns that scenario.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No scenario should be in the cluster-tool package

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 1ef40742. BatchOperatorTerminalTieScenario was moved out of cluster-tool and is now owned by flow-batch-operator-terminal-tie; it imports the shared dispute base from the private @wireio/batch-operator-dispute-scenario support package.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No scenario should be in the cluster-tool package

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 1ef40742. BatchOperatorSlashingScenario was moved out of cluster-tool and is now owned by flow-batch-operator-slashing; it imports the shared dispute base from the private @wireio/batch-operator-dispute-scenario support package.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No scenario should be in the cluster-tool package

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 1ef40742. The dispute-specific constants were moved out of cluster-tool into the private @wireio/batch-operator-dispute-scenario support package and are no longer part of the cluster-tool surface.

type OutpostInboundTips
} from "../InboundTipReader.js"
import { SlashingScenarioConstants as Constants } from "../SlashingScenarioConstants.js"
import { BatchOperatorDisputeConstants as Constants } from "../batchOperatorDisputeConstants.js"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No scenario should be in the cluster-tool package

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 1ef40742. The dispute-specific scenario steps were moved out of cluster-tool into the private @wireio/batch-operator-dispute-scenario support package; cluster-tool retains only the generic typed contract-step primitives they use.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No scenario should be in the cluster-tool package

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 1ef40742. BatchOperatorDisputeScenario now lives in the private @wireio/batch-operator-dispute-scenario support package rather than cluster-tool. The current head keeps concrete scenarios in their flow packages and only generic flow utilities in cluster-tool.

@huangminghuang
huangminghuang marked this pull request as draft October 21, 2026 18:57
@huangminghuang
huangminghuang marked this pull request as ready for review October 22, 2026 21:47
@huangminghuang
huangminghuang requested a review from jglanz October 22, 2026 21:50

@jglanz jglanz left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@huangminghuang you need to review these with your human eyes & claude OMC before asking for a reviewer; you have again violated package naming approach with batch-operator-dispute-scenario @heifner

@heifner

heifner commented Oct 23, 2026

Copy link
Copy Markdown
Contributor

This PR isn't needed for WIRE-362. The fix is Wire-Network/wire-sysio#581 (merged 2026-08-28), and contracts/tests/sysio.msgch_chain_tests.cpp on master already drives the terminal ties through chkcons:

  • chkcons_opens_dispute_for_one_to_one_tie: E=2; the dispute opens, a Tier-1 vote resolves it, outpcons records the winner
  • chkcons_opens_dispute_for_three_to_three_tie: E=6
  • chkcons_waits_for_incomplete_two_way_split: a silent third operator means no dispute; the late delivery forms the majority
  • chkcons_retries_terminal_tie_after_tier_one_registration
  • dispute_resolves_while_envelopes_are_pruned: 1–1, vote, then advance slashes the loser and the winner stays ACTIVE
  • short_group_after_slash_still_reaches_consensus: 3 seats with one slashed leaves 2 eligible

The new flow's dispute operators run no daemon, and the flow pushes every msgch::deliver itself. No plugin or outpost code takes part in the tie; it reruns the same depot contract path inside a full cluster. flow-batch-operator-slashing already covers the live dispute → vote → unpause → slash path.

The one combination no single contract test covers is 3 configured seats, one terminated, then a 1–1 tie. It reduces to the 2-member case because the dispute check counts only ACTIVE members. If we want it pinned, it's one more case in sysio.msgch_chain_tests.cpp, not a new flow.

Against that, this PR is +2,101/−663 lines across 43 files: a new private package, a restructure of the slashing flow, and another cluster bootstrap in every e2e run.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants