Repository navigation
feat(staking): support the two-step operator rotation - #104
Merged
Merged
Conversation
CON-715 removed ValidatorWalletBlueprint.setOperator in favour of initiateOperatorTransfer + completeOperatorTransfer. Against a consensus deployment carrying that change, set_operator fails with ABIFunctionNotFound: the function 'setOperator' was not found in this contract's abi. Adds the two calls plus cancel_operator_transfer and the get_pending_operator view, and keeps set_operator for deployments that still expose it. This SDK had no proof-of-possession support at all, so the encoding is new here: genlayer_py.staking.operator_registration mirrors genlayer-js's createOperatorRegistration — keccak over abi.encode(domain, chainId, registrar, owner, pubKey[0], pubKey[1]), signed EIP-191 by the operator key. Both SDKs sign proofs the same contract verifies, so the test pins the exact vector genlayer-js asserts (domain hash, message hash and signature bytes) rather than only checking internal consistency. The registrar differs by flow and is the easy thing to get wrong: the factory verifies a validator join, the wallet verifies a rotation. get_operator_transfer_context builds the wallet-bound context and reads owner() from the wallet rather than assuming the caller is the owner, and initiate_operator_transfer verifies the proof locally so a factory-bound one fails with a clear message instead of an opaque revert. A test pins that a join proof does not verify for a rotation. Not addressed here: validator_join still encodes the retired validatorJoin() / validatorJoin(address) overloads, which CON-666 replaced with validatorJoin(uint256[2],bytes). That is the same migration and now has the helper it needs, but it changes a public signature, so it wants its own change. Verified: pytest tests/unit — 141 passing.
|
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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Depends-On: genlayerlabs/genlayer-consensus#1290
What
Adds
initiate_operator_transfer/complete_operator_transfer(pluscancel_operator_transferand theget_pending_operatorview), and theproof-of-possession helper they need.
Why
CON-715 removed
ValidatorWalletBlueprint.setOperatorin favour of a two-steprotation. Against consensus #1290 the Python SDK fails at the first step:
That is currently red on every e2e run for this closure —
045_validator_set_operatorand
079_operator_key_rotationin thegenlayer-py (dev-env)lane, with thesame failure reproducing in the js and cli lanes for the same reason.
set_operatoris kept, since consensusv0.6-devstill exposes it and thedefault e2e matrix pins that branch.
The proof binding
This SDK had no possession-proof support, so
genlayer_py.staking.operator_registrationis new. It mirrors genlayer-js's
createOperatorRegistration: keccak overabi.encode(domain, chainId, registrar, owner, pubKey[0], pubKey[1]), signedEIP-191 by the operator key.
The registrar differs by flow, and getting it wrong fails silently — the proof
just does not verify:
validatorJoininitiateOperatorTransferget_operator_transfer_contextbuilds the wallet-bound context and readsowner()from the wallet rather than assuming the caller is the owner, so amismatch surfaces as a clear error instead of an
onlyOwnerrevert.Cross-language vector
Both SDKs sign proofs the same contract verifies, so the test asserts the
exact bytes genlayer-js asserts — domain hash, message hash, and signature —
not merely internal consistency. A divergence here would be a real
interoperability break.
Known gap, deliberately not in this PR
validator_joinstill encodes the retiredvalidatorJoin()/validatorJoin(address)overloads that CON-666 replaced withvalidatorJoin(uint256[2],bytes). It is the same migration and now has thehelper it needs, but it changes a public signature, so it deserves its own
change and its own review.
Validation
pytest tests/unit— 141 passing.