core/vm: reject duplicate bridge validators at Pasteur#3623
Conversation
|
|
||
| func (t validatorDuplicateTracker) check(idx int, value []byte) error { | ||
| key := string(value) | ||
| if firstIdx, ok := t.seen[key]; ok { |
There was a problem hiding this comment.
are bls key and RelayerAddress allowed to stay unset? represent by zero value
There was a problem hiding this comment.
Yes. Those two fields are allowed to be unset upstream. In our fixed-width decode path, "unset" is represented as zero-filled bytes, so I treat empty/nil and all-zero as the same unset state and exclude only
that case from duplicate detection.
| // input: | ||
| // | chainID | height | nextValidatorSetHash | [{validator pubkey, voting power, relayer address, relayer bls pubkey}] | | ||
| // | 32 bytes | 8 bytes | 32 bytes | [{32 bytes, 8 bytes, 20 bytes, 48 bytes}] | | ||
| func DecodeConsensusState(input []byte) (ConsensusState, error) { |
There was a problem hiding this comment.
how about
- func DecodeConsensusState(input []byte) (ConsensusState, error)
--> func DecodeConsensusState(input []byte, requireUniqueValidators bool) (ConsensusState, error) - delete DecodeConsensusStateWithValidation
| // input: | ||
| // consensus state length | consensus state | light block | | ||
| // 32 bytes | | | | ||
| func DecodeLightBlockValidationInput(input []byte) (*ConsensusState, *types.LightBlock, error) { |
There was a problem hiding this comment.
how about
- func DecodeLightBlockValidationInput(input []byte) (*ConsensusState, *types.LightBlock, error)
--> func DecodeLightBlockValidationInput(input []byte, requireUniqueValidators bool) (*ConsensusState, *types.LightBlock, error) - delete DecodeLightBlockValidationInputWithValidation
| return "COMET_BFT_LIGHT_BLOCK_VALIDATE_HERTZ" | ||
| } | ||
|
|
||
| type cometBFTLightBlockValidateHertzMendel struct { |
There was a problem hiding this comment.
how about
cometBFTLightBlockValidateHertzMendel --> cometBFTLightBlockValidateMendel?
because when Mendel enabled, Hertz must be already enalbed
|
delay to Pasteur HF after discussion |
|
0x66 (blsSignatureVerify) is left unchanged — it is a generic BLS primitive and does not require unique pubkeys. |
Summary
0x66) and CometBFT light block validation (0x67)Details
This change introduces Pasteur-only behavior for the bridge validator precompiles.
For BLS signature verification, the Pasteur variant rejects inputs that repeat the same validator pubkey in the aggregated signer set. Pre-Pasteur behavior is preserved.
For CometBFT light block validation, the Pasteur variant validates that validator sets do not contain duplicate identities. The validation covers validator address, consensus pubkey, BLS key, and relayer
address, and is applied when decoding both the trusted consensus state and the incoming light block validator set.
Why
Duplicate bridge validators can allow malformed validator sets or signer lists to bypass uniqueness assumptions in bridge verification logic. Pasteur now enforces uniqueness at the precompile boundary instead
of relying on callers to sanitize inputs.