# The merge ## Context Because we need to use bn256 for IBC brigde to ethereum. We'll start the chain with `ed25519`, when other chain ready to verify `bn256` signatures, we'll change to use `bn256` keys types to all validators. ### Solution - Leverage from validator node rekeying, we'll create new msg for validator so they can move their validator consensus keys type from `ed25519` to `bn256`. - We will set a timeline for this, if validator don't change theier key types, the validator node will be jailed (for ensure that all validator consensus keys will be `bn256`) - We don't need to make any update on consensus logic in Tendermint because Tendermint does not have any mapping information of consensus key and validator operator key, meaning that from Tendermint point of view, a consensus key rotation of a validator is simply a replacement of a consensus key to another. > [name=Blas Rodriguez Irizar] How don't we need to make updates on consensus? There are references to pub keys everywhere > https://github.com/cometbft/cometbft/blob/main/consensus/state.go#L105 https://github.com/cometbft/cometbft/blob/main/state/state.go#L65-L67 https://github.com/cometbft/cometbft/blob/main/proto/tendermint/types/validator.pb.go#L121 > I guess what Vuong means here is that we won't change any of the code responsible for Tendermint consensus. The only thing we change in Tendermint code is adding a key implementation. However we do change Tendermint consensus state via `abci.ValidatorUpdate`. understood! ### Pseudo procedure for move validator consensus keys type from `ed25519` to `bn256`. > [name=Blas Rodriguez Irizar] This is really good. Can we have a test for this? Disregarding the IBC piece for now it's OK. Just to ensure that the chain can keep operating after the signature switch. * Upgrade chain for allow both `bn256` and `ed25519` for validator consensus. Set the timeline to move from `ed25519` to `bn256`. We already have code for this, use sdk47 and lastest comet-bft. * Validators create new random consensus key that based on `bn256`. * Validators create and broadcast a transaction with a `MsgValRotateConsPubKey` that states the new consensus key is now coupled with the validator operator with signature from the validator's operator key. * Old consensus key becomes unable to participate on consensus immediately after the update of key mapping state on-chain. Validator can validate block with `bn256` schema. * To ensure IBC connection to Ethereum, all validators need to move to bn256. If a validator does not change their consensus key by the deadline, they will be jailed. | IBC to Ethreum | Allowed keys types for valset | Verifiable IBC client in counterparty chain | | -------- | -------- | -------- | | No | ed25519 | Only verify `ed25519` signature scheme | | No | ed25519 and bn256 | Both `ed25519` and `bn256` | | Yes | bn256 | Both `ed25519` and `bn256` | *We're assuming IBC connection to Etherum will be ready if all validator switch to bn256 key types* ### Workflow 1. Upgrade chain for allow both `bn256` and `ed25519` for validator consensus key pair. 1. The validator generates a new consensus keypair. 2. The validator generates and signs a `MsgRotateConsPubKey` tx with their operator key and new ConsPubKey ```go type MsgRotateConsPubKey struct { ValidatorAddress sdk.ValAddress NewPubKey crypto.PubKey } ``` 3. `handleMsgRotateConsPubKey` gets `MsgRotateConsPubKey`, calls `RotateConsPubKey` with emits event 4. `RotateConsPubKey` * checks if `NewPubKey` is not duplicated on `ValidatorsByConsAddr` * checks if `NewPubKey` is `bn256` pubkey * overwrites `NewPubKey` in `validator.ConsPubKey` * deletes old `ValidatorByConsAddr` * `SetValidatorByConsAddr` for `NewPubKey` * Add `ConsPubKeyRotationHistory` for tracking rotation ```go type ConsPubKeyRotationHistory struct { OperatorAddress sdk.ValAddress OldConsPubKey crypto.PubKey NewConsPubKey crypto.PubKey RotatedHeight int64 } ``` 5. checks if there is `ConsPubKeyRotationHistory` with `ConsPubKeyRotationHistory.RotatedHeight == ctx.BlockHeight()` and if so, generates 2 `ValidatorUpdate`, one for a remove validator and one for create new validator ```go abci.ValidatorUpdate{ PubKey: tmtypes.TM2PB.PubKey(OldConsPubKey), Power: 0, } abci.ValidatorUpdate{ PubKey: tmtypes.TM2PB.PubKey(NewConsPubKey), Power: v.ConsensusPower(), } ``` 6. at `previousVotes` Iteration logic of `AllocateTokens`, `previousVote` using `OldConsPubKey` match up with `ConsPubKeyRotationHistory`, and replace validator for token allocation 7. Migrate `ValidatorSigningInfo` and `ValidatorMissedBlockBitArray` from `OldConsPubKey` to `NewConsPubKey` 8. Upgrade chain for only use `bn256`. Also we need to jail validators who don't move to bn256.