@@ -37,18 +37,28 @@ type ConsensusState struct {
3737}
3838
3939type validatorDuplicateTracker struct {
40- field string
41- seen map [string ]int
40+ field string
41+ seen map [string ]int
42+ ignoreZero bool
4243}
4344
44- func newValidatorDuplicateTracker (field string , size int ) validatorDuplicateTracker {
45+ func newValidatorDuplicateTracker (field string , size int , ignoreZero bool ) validatorDuplicateTracker {
4546 return validatorDuplicateTracker {
46- field : field ,
47- seen : make (map [string ]int , size ),
47+ field : field ,
48+ seen : make (map [string ]int , size ),
49+ ignoreZero : ignoreZero ,
4850 }
4951}
5052
5153func (t validatorDuplicateTracker ) check (idx int , value []byte ) error {
54+ if t .ignoreZero {
55+ // Optional bridge fields may be omitted in source validators or zero-filled by
56+ // fixed-width decoding. Both forms mean "unset" and should not count as duplicates.
57+ if len (value ) == 0 || isZeroBytes (value ) {
58+ return nil
59+ }
60+ }
61+
5262 key := string (value )
5363 if firstIdx , ok := t .seen [key ]; ok {
5464 return fmt .Errorf ("duplicate validator %s #%d and #%d: %X" , t .field , firstIdx , idx , value )
@@ -57,16 +67,28 @@ func (t validatorDuplicateTracker) check(idx int, value []byte) error {
5767 return nil
5868}
5969
70+ func isZeroBytes (value []byte ) bool {
71+ if len (value ) == 0 {
72+ return false
73+ }
74+ for _ , b := range value {
75+ if b != 0 {
76+ return false
77+ }
78+ }
79+ return true
80+ }
81+
6082func validateUniqueValidatorSet (validatorSet * types.ValidatorSet ) error {
6183 if validatorSet == nil {
6284 return nil
6385 }
6486
6587 size := len (validatorSet .Validators )
66- addresses := newValidatorDuplicateTracker ("address" , size )
67- pubKeys := newValidatorDuplicateTracker ("pubkey" , size )
68- blsKeys := newValidatorDuplicateTracker ("bls key" , size )
69- relayerAddresses := newValidatorDuplicateTracker ("relayer address" , size )
88+ addresses := newValidatorDuplicateTracker ("address" , size , false )
89+ pubKeys := newValidatorDuplicateTracker ("pubkey" , size , false )
90+ blsKeys := newValidatorDuplicateTracker ("bls key" , size , true )
91+ relayerAddresses := newValidatorDuplicateTracker ("relayer address" , size , true )
7092
7193 for idx , validator := range validatorSet .Validators {
7294 if validator == nil || validator .PubKey == nil {
@@ -190,7 +212,7 @@ func (cs *ConsensusState) ApplyLightBlock(block *types.LightBlock, isHertz bool)
190212// input:
191213// | chainID | height | nextValidatorSetHash | [{validator pubkey, voting power, relayer address, relayer bls pubkey}] |
192214// | 32 bytes | 8 bytes | 32 bytes | [{32 bytes, 8 bytes, 20 bytes, 48 bytes}] |
193- func decodeConsensusState (input []byte , requireUniqueValidators bool ) (ConsensusState , error ) {
215+ func DecodeConsensusState (input []byte , requireUniqueValidators bool ) (ConsensusState , error ) {
194216 minimumLength := chainIDLength + heightLength + validatorSetHashLength
195217 inputLen := uint64 (len (input ))
196218 if inputLen <= minimumLength || (inputLen - minimumLength )% singleValidatorBytesLength != 0 {
@@ -254,18 +276,10 @@ func decodeConsensusState(input []byte, requireUniqueValidators bool) (Consensus
254276 return consensusState , nil
255277}
256278
257- func DecodeConsensusState (input []byte ) (ConsensusState , error ) {
258- return decodeConsensusState (input , false )
259- }
260-
261- func DecodeConsensusStateWithValidation (input []byte ) (ConsensusState , error ) {
262- return decodeConsensusState (input , true )
263- }
264-
265279// input:
266280// consensus state length | consensus state | light block |
267281// 32 bytes | | |
268- func decodeLightBlockValidationInput (input []byte , requireUniqueValidators bool ) (* ConsensusState , * types.LightBlock , error ) {
282+ func DecodeLightBlockValidationInput (input []byte , requireUniqueValidators bool ) (* ConsensusState , * types.LightBlock , error ) {
269283 if uint64 (len (input )) <= consensusStateLengthBytesLength {
270284 return nil , nil , errors .New ("invalid input" )
271285 }
@@ -280,7 +294,7 @@ func decodeLightBlockValidationInput(input []byte, requireUniqueValidators bool)
280294 return nil , nil , fmt .Errorf ("expected payload size %d, actual size: %d" , consensusStateLengthBytesLength + csLen , len (input ))
281295 }
282296
283- cs , err := decodeConsensusState (input [consensusStateLengthBytesLength :consensusStateLengthBytesLength + csLen ], requireUniqueValidators )
297+ cs , err := DecodeConsensusState (input [consensusStateLengthBytesLength :consensusStateLengthBytesLength + csLen ], requireUniqueValidators )
284298 if err != nil {
285299 return nil , nil , err
286300 }
@@ -303,14 +317,6 @@ func decodeLightBlockValidationInput(input []byte, requireUniqueValidators bool)
303317 return & cs , block , nil
304318}
305319
306- func DecodeLightBlockValidationInput (input []byte ) (* ConsensusState , * types.LightBlock , error ) {
307- return decodeLightBlockValidationInput (input , false )
308- }
309-
310- func DecodeLightBlockValidationInputWithValidation (input []byte ) (* ConsensusState , * types.LightBlock , error ) {
311- return decodeLightBlockValidationInput (input , true )
312- }
313-
314320// output:
315321// | validatorSetChanged | empty | consensusStateBytesLength | new consensusState |
316322// | 1 byte | 23 bytes | 8 bytes | |
0 commit comments