fix: align Python SDK consumers with the resolution-kernel train - #109
Conversation
The train withdraws reads this SDK is built on, and none of them fail in a
way a caller would notice:
- getTransactionData(txId, timestamp) is gone. It answered with a status
PROJECTED at a caller-supplied clock; the chain now keeps the stored
record and the projection apart, behind getStoredTransactionData(txId)
and getTransactionLifecycle. This is what the py lane traceback rooted
at, and it is a hard failure -- web3 cannot find the function.
- activeValidators() and activeValidatorsCount() are gone. Committee
capacity is 1,543 seats and an address[] that long overruns the
return-size limit, so the joined registry is only readable in slices.
- validatorView() dropped its left/right/parent tree links, so the tuple
went from twelve fields to nine.
- ReadyToFinalize was removed from TransactionStatus at ordinal 11 and
the three above it shifted down. Left alone, a ValidatorsTimeout
transaction decoded as READY_TO_FINALIZE -- no error, the wrong answer.
- previousStatus was dropped from the Transaction struct that
getTransactionAllData returns, so status sits at index 2 and the rest
moved up one slot.
The transaction read now detects rather than assumes: chains are upgraded
independently, so it picks whichever of the two reads the chain's own ABI
offers. Both return the same 23-field struct -- only field [0] was renamed
currentTimestamp to observedAt -- so the positional decode is untouched.
active_validators() pages the joined registry: validatorsJoinedCount()
bounds the walk and getValidatorsJoined(start, size) returns each page. The
count is read first so a registry that grows underneath the walk cannot
spin the loop, and a short page means it shrank instead. Page size is 64,
matching genlayer-node's walk over the same registry.
TransactionStatus keeps its READY_TO_FINALIZE member, because the node
still reports that state. What changed is that no chain value decodes to
it, so the name-to-number map no longer carries an ordinal for it: 11
belongs to VALIDATORS_TIMEOUT now, and there is no free number that would
not collide.
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
The train adaptation routed every appeal action through the resolution-kernel lifecycle reads. Studio chains (localnet and studionet, which share chain id 61999) run the studio-embedded consensus, which predates the train: its ConsensusData exposes neither getTransactionLifecycle nor estimateLatestAppealCharge, and its ConsensusMain, refetched from the simulator RPC, still declares submitAppeal(bytes32). The decision-guarded encoding therefore aborted with "value has 2 items when 1 were expected" before the call was ever sent. The sibling genlayer-js defect failed the studio suites of e2e run 33112369501. This mirrors its fix, genlayer-js 04a0bde: guard each affected action on the studio chain check that transactions.actions.get_transaction already uses, and reinstate the pre-train behaviour recovered from the v0.19-dev base. - appeal_transaction encodes submitAppeal(bytes32) against the chain's own ConsensusMain ABI. - top_up_and_submit_appeal encodes topUpAndSubmitAppeal(bytes32, FeesDistribution) without a decision id. - get_appeal_quote, get_appeal_charge and get_min_appeal_bond report the missing quote surface with the error the base already raised on studio. - Both appeal writes keep the base value semantics: the pre-train resolver read the bond through FeeManager/RoundsStorage, which studio chains never configure, so an omitted value raises the base message verbatim. A call that binds to no decision cannot honour a decision guard, so expected_decision_id is refused there. can_appeal and the rounds-storage reads already returned their base error on studio: their missing-contract guards run before any train read, so they are left alone. This SDK has no finalizeTransaction, resolveTransactions or finalizeDecisions surface to adapt. The train path is unchanged for non-studio chains. The appeal tests that pin it now build a train chain client, since the shared helper defaulted to the studio chain id.
Expose materialized transaction progress as a small state-discriminated lifecycle, make receipt waits target stored decisions or finalization, and keep projection/action/source/decision identity in the explicit advanced read.\n\nRemove the old public status compatibility surface and normalize advanced protocol names, decimal decision IDs, and evaluation timestamps across local and contract-backed networks.\n\nValidation: 189 offline unit tests with 13 old-deployment tests excluded; 12 Asimov smoke tests; focused lifecycle tests; E2E collection; docs; Black; build and installed-wheel smoke.
MuncleUscles
left a comment
There was a problem hiding this comment.
Reviewed the decision-bound train calls, native current-Studio appeal behavior, and method-not-found-only lifecycle fallback on this exact head. Unit coverage, formatting, and generated docs are green. Approving; composed behavior remains gated by the stack E2E.
9ee4386 to
f2c1e8a
Compare
Delivery context
Depends-On: genlayerlabs/genlayer-consensus#1307
Depends-On: genlayerlabs/genlayer-node#1800
Problem and outcome
This SDK line targets the resolution-kernel/v0.6 train. It removes the obsolete
ReadyToFinalizestate, separates stored consumer lifecycle from protocol projection, and aligns fee construction and lifecycle reads with current Consensus and Node interfaces.Studio v0.123 now exposes authoritative lifecycle identity and appeal-charge RPCs. Python appeals therefore use the same decision-bound
submitAppeal(bytes32,uint256)andtopUpAndSubmitAppeal(bytes32,uint256,FeesDistribution)shapes as deployed Consensus. Omitted decision/value inputs are resolved from the authoritative Studio or Consensus quote, andcan_appealchecks the same active decision.Fee estimates mirror the current Consensus deposit quote: submission-time max price, combined funding-overlay gross-up, absolute/saturated committee ladder, all configured rotations, and successful-appellant reserve.
Implementation and validation
get_transaction_lifecycleexposes projection/action/source/decision identity.gen_getTransactionLifecycle; Studio appeal quotes usegen_estimateLatestAppealCharge.git diff --check: passing.Current head:
9ee438604c6a4d8e6783b23d61e360aa3405d893.The composed Studio/Consensus behavior is qualified by genlayerlabs/genlayer-e2e#756, stacked on #748.
Risk and rollback
This is intentionally incompatible with pre-train decision-free Studio entrypoints. Older deployments must use their matching SDK. Rollback is the commits on this PR branch; no persisted data is changed by the SDK.