@@ -410,6 +410,31 @@ func (c *Bor) verifyCascadingFields(chain consensus.ChainHeaderReader, header *t
410410 if err != nil {
411411 return err
412412 }
413+ // Verify the validator list match the local contract
414+ if isSprintStart (number + 1 , c .config .Sprint ) {
415+ newValidators , err := c .GetCurrentValidatorsByBlockNrOrHash (context .Background (), rpc .BlockNumberOrHashWithNumber (rpc .LatestBlockNumber ), number + 1 )
416+ if err != nil {
417+ return err
418+ }
419+
420+ sort .Sort (ValidatorsByAddress (newValidators ))
421+
422+ headerVals , err := ParseValidators (header .Extra [extraVanity : len (header .Extra )- extraSeal ])
423+
424+ if err != nil {
425+ return err
426+ }
427+
428+ if len (newValidators ) != len (headerVals ) {
429+ return errInvalidSpanValidators
430+ }
431+
432+ for i , val := range newValidators {
433+ if ! bytes .Equal (val .HeaderBytes (), headerVals [i ].HeaderBytes ()) {
434+ return errInvalidSpanValidators
435+ }
436+ }
437+ }
413438
414439 // verify the validator list in the last sprint block
415440 if isSprintStart (number , c .config .Sprint ) {
@@ -1005,6 +1030,59 @@ func (c *Bor) GetCurrentValidators(headerHash common.Hash, blockNumber uint64) (
10051030 return valz , nil
10061031}
10071032
1033+ // GetCurrentValidatorsByBlockNrOrHash get current validators
1034+ func (c * Bor ) GetCurrentValidatorsByBlockNrOrHash (ctx context.Context , blockNrOrHash rpc.BlockNumberOrHash , blockNumber uint64 ) ([]* Validator , error ) {
1035+ ctx , cancel := context .WithCancel (ctx )
1036+ defer cancel ()
1037+
1038+ // method
1039+ const method = "getBorValidators"
1040+
1041+ data , err := c .validatorSetABI .Pack (method , big .NewInt (0 ).SetUint64 (blockNumber ))
1042+ if err != nil {
1043+ log .Error ("Unable to pack tx for getValidator" , "error" , err )
1044+ return nil , err
1045+ }
1046+
1047+ // call
1048+ msgData := (hexutil .Bytes )(data )
1049+ toAddress := common .HexToAddress (c .config .ValidatorContract )
1050+ gas := (hexutil .Uint64 )(uint64 (math .MaxUint64 / 2 ))
1051+
1052+ result , err := c .ethAPI .Call (ctx , ethapi.TransactionArgs {
1053+ Gas : & gas ,
1054+ To : & toAddress ,
1055+ Data : & msgData ,
1056+ }, blockNrOrHash , nil )
1057+ if err != nil {
1058+ return nil , err
1059+ }
1060+
1061+ var (
1062+ ret0 = new ([]common.Address )
1063+ ret1 = new ([]* big.Int )
1064+ )
1065+
1066+ out := & []interface {}{
1067+ ret0 ,
1068+ ret1 ,
1069+ }
1070+
1071+ if err := c .validatorSetABI .UnpackIntoInterface (out , method , result ); err != nil {
1072+ return nil , err
1073+ }
1074+
1075+ valz := make ([]* Validator , len (* ret0 ))
1076+ for i , a := range * ret0 {
1077+ valz [i ] = & Validator {
1078+ Address : a ,
1079+ VotingPower : (* ret1 )[i ].Int64 (),
1080+ }
1081+ }
1082+
1083+ return valz , nil
1084+ }
1085+
10081086func (c * Bor ) checkAndCommitSpan (
10091087 state * state.StateDB ,
10101088 header * types.Header ,
0 commit comments