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. |
| common.BytesToAddress([]byte{0x1, 0x00}): &p256Verify{eip7951: true}, | ||
| } | ||
|
|
||
| var PrecompiledContractsPasteur = func() PrecompiledContracts { |
There was a problem hiding this comment.
list precompiles directly like others
| for k := range PrecompiledContractsPrague { | ||
| PrecompiledAddressesPrague = append(PrecompiledAddressesPrague, k) | ||
| } | ||
| for k := range PrecompiledContractsPasteur { |
There was a problem hiding this comment.
move after PrecompiledContractsOsaka
Pull Request ReviewThis PR introduces Pasteur-specific precompile routing by adding a new Sensitive ContentNo sensitive content detected. Security IssuesNo serious security issues detected. Generated by Hashdit Bot. This tool can absolutely NOT replace manual audits. |
… block at Pasteur Builds on the Pasteur precompile set introduced in bnb-chain#3623. The legacy v1 Tendermint light-client precompiles 0x64 (tmHeaderValidate) and 0x65 (iavlMerkleProofValidate) are only reachable via the deprecated BC<->BSC cross-chain stack (contracts/deprecated/), which no longer exists. Rename the existing *Nano suspend handlers to tmHeaderValidateDeprecated / iavlMerkleProofValidateDeprecated (error "deprecated") and map 0x64/0x65 to them in the Pasteur set, deprecating them from Pasteur. For the v2 cometBFT light-client (0x67), the verification work scales with the light block's validator/signature count while the gas was flat. Price the Pasteur variant's RequiredGas per input byte (CometBFTLightBlockValidatePerByteGas) so gas tracks the real CPU/memory cost (cf. the per-key pricing of 0x66 blsSignatureVerify). The pre-Pasteur Hertz variant keeps the flat gas so earlier blocks replay identically. Note: the per-byte rate is tunable; raising 0x67 gas affects the live Greenfield/op-stack relayer gas budget and should be coordinated. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… block at Pasteur Builds on the Pasteur precompile set introduced in bnb-chain#3623. The legacy v1 Tendermint light-client precompiles 0x64 (tmHeaderValidate) and 0x65 (iavlMerkleProofValidate) are only reachable via the deprecated BC<->BSC cross-chain stack (contracts/deprecated/), which no longer exists. Rename the existing *Nano suspend handlers to tmHeaderValidateDeprecated / iavlMerkleProofValidateDeprecated (error "deprecated") and map 0x64/0x65 to them in the Pasteur set, deprecating them from Pasteur. For the v2 cometBFT light-client (0x67), the verification work scales with the light block's validator/signature count while the gas was flat. Price the Pasteur variant's RequiredGas per input byte (CometBFTLightBlockValidatePerByteGas) so gas tracks the real CPU/memory cost (cf. the per-key pricing of 0x66 blsSignatureVerify). The pre-Pasteur Hertz variant keeps the flat gas so earlier blocks replay identically. Note: the per-byte rate is tunable; raising 0x67 gas affects the live Greenfield/op-stack relayer gas budget and should be coordinated. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… block at Pasteur (#3726) Builds on the Pasteur precompile set introduced in #3623. The legacy v1 Tendermint light-client precompiles 0x64 (tmHeaderValidate) and 0x65 (iavlMerkleProofValidate) are only reachable via the deprecated BC<->BSC cross-chain stack (contracts/deprecated/), which no longer exists. Rename the existing *Nano suspend handlers to tmHeaderValidateDeprecated / iavlMerkleProofValidateDeprecated (error "deprecated") and map 0x64/0x65 to them in the Pasteur set, deprecating them from Pasteur. For the v2 cometBFT light-client (0x67), the verification work scales with the light block's validator/signature count while the gas was flat. Price the Pasteur variant's RequiredGas per input byte (CometBFTLightBlockValidatePerByteGas) so gas tracks the real CPU/memory cost (cf. the per-key pricing of 0x66 blsSignatureVerify). The pre-Pasteur Hertz variant keeps the flat gas so earlier blocks replay identically. Note: the per-byte rate is tunable; raising 0x67 gas affects the live Greenfield/op-stack relayer gas budget and should be coordinated. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.