diff --git a/consensus/bor/heimdall/span/spanner.go b/consensus/bor/heimdall/span/spanner.go index 7734d016f3..99c361f044 100644 --- a/consensus/bor/heimdall/span/spanner.go +++ b/consensus/bor/heimdall/span/spanner.go @@ -111,7 +111,7 @@ func (c *ChainSpanner) GetCurrentValidatorsByBlockNrOrHash(ctx context.Context, return valz, nil } -// Try to get bor validators with Id from ValidatorSet contract by querying each element on mapping(uint256 => Validator[]) public producers +// tryGetBorValidatorsWithId Try to get bor validators with Id from ValidatorSet contract by querying each element on mapping(uint256 => Validator[]) public producers // If fails then returns GetBorValidators without id func (c *ChainSpanner) tryGetBorValidatorsWithId(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash, blockNumber uint64, toAddress common.Address, gas hexutil.Uint64) ([]*valset.Validator, error) { firstEndBlock, err := c.getFirstEndBlock(ctx, blockNrOrHash, toAddress, gas) diff --git a/consensus/bor/snapshot.go b/consensus/bor/snapshot.go index 72c7bc1ab1..ae383cbf6f 100644 --- a/consensus/bor/snapshot.go +++ b/consensus/bor/snapshot.go @@ -5,6 +5,7 @@ import ( "encoding/json" "github.com/ethereum/go-ethereum/consensus/bor/valset" + "github.com/ethereum/go-ethereum/log" lru "github.com/hashicorp/golang-lru" @@ -159,8 +160,11 @@ func (s *Snapshot) apply(headers []*types.Header, c *Bor) (*Snapshot, error) { v := getUpdatedValidatorSet(snap.ValidatorSet.Copy(), newVals) v.IncrementProposerPriority(1) - valsWithId, _ := c.spanner.GetCurrentValidatorsByHash(context.Background(), header.Hash(), header.Number.Uint64()) - v.IncludeIds(valsWithId) + if v.CheckEmptyId() { + log.Warn("Empty id found on validator set. Querying on the validatorSet contract") + valsWithId, _ := c.spanner.GetCurrentValidatorsByHash(context.Background(), header.Hash(), header.Number.Uint64()) + v.IncludeIds(valsWithId) + } snap.ValidatorSet = v } } diff --git a/consensus/bor/valset/validator_set.go b/consensus/bor/valset/validator_set.go index 5842ba7e55..400a5ff8fb 100644 --- a/consensus/bor/valset/validator_set.go +++ b/consensus/bor/valset/validator_set.go @@ -128,6 +128,18 @@ func (vals *ValidatorSet) IncludeIds(valsWithId []*Validator) { } } +// CheckEmptyId checks if any validator in the ValidatorSet has an empty ID (ID == 0). +// Returns true if at least one validator has an empty ID. +// Returns false if all validators have non-zero IDs or if the ValidatorSet is empty. +func (vals *ValidatorSet) CheckEmptyId() bool { + for _, val := range vals.Validators { + if val.ID == 0 { + return true + } + } + return false +} + func (vals *ValidatorSet) RescalePriorities(diffMax int64) { if vals.IsNilOrEmpty() { panic("empty validator set") diff --git a/consensus/bor/valset/validator_set_test.go b/consensus/bor/valset/validator_set_test.go index 5c6ff2a1b9..f4e30eed8d 100644 --- a/consensus/bor/valset/validator_set_test.go +++ b/consensus/bor/valset/validator_set_test.go @@ -257,3 +257,59 @@ func TestValidatorSet_IncludeIds_EmptySet(t *testing.T) { assert.Equal(t, 0, valSet.Size(), "ValidatorSet remains empty") } + +func TestCheckEmptyId(t *testing.T) { + tests := []struct { + name string + validatorSet ValidatorSet + expected bool + }{ + { + name: "Empty ValidatorSet", + validatorSet: ValidatorSet{Validators: []*Validator{}}, + expected: false, + }, + { + name: "All Validators with Non-Zero IDs", + validatorSet: ValidatorSet{ + Validators: []*Validator{ + {ID: 1}, + {ID: 2}, + {ID: 3}, + }, + }, + expected: false, + }, + { + name: "One Validator with ID Zero", + validatorSet: ValidatorSet{ + Validators: []*Validator{ + {ID: 0}, + {ID: 2}, + {ID: 3}, + }, + }, + expected: true, + }, + { + name: "All Validators with ID Zero", + validatorSet: ValidatorSet{ + Validators: []*Validator{ + {ID: 0}, + {ID: 0}, + {ID: 0}, + }, + }, + expected: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := tt.validatorSet.CheckEmptyId() + if result != tt.expected { + t.Errorf("expected %v, got %v", tt.expected, result) + } + }) + } +}