From d8b870216a6eb5b30ad26d744ab414e6af384471 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Tue, 22 Mar 2022 14:49:48 +0200 Subject: [PATCH 1/2] FEAT: Refactor code to use new interface --- epochStart/interface.go | 2 +- epochStart/metachain/legacySystemSCs.go | 2 +- epochStart/metachain/stakingDataProvider.go | 11 ++-- .../metachain/stakingDataProvider_test.go | 23 ++++--- epochStart/metachain/systemSCs_test.go | 2 +- epochStart/mock/stakingDataProviderStub.go | 6 +- state/interface.go | 2 - state/validatorsInfoMap.go | 62 ------------------- state/validatorsInfoMap_test.go | 32 ---------- 9 files changed, 22 insertions(+), 120 deletions(-) diff --git a/epochStart/interface.go b/epochStart/interface.go index f170416f771..5fc31ce340d 100644 --- a/epochStart/interface.go +++ b/epochStart/interface.go @@ -152,7 +152,7 @@ type StakingDataProvider interface { GetNodeStakedTopUp(blsKey []byte) (*big.Int, error) PrepareStakingData(keys map[uint32][][]byte) error FillValidatorInfo(blsKey []byte) error - ComputeUnQualifiedNodes(validatorInfos map[uint32][]*state.ValidatorInfo) ([][]byte, map[string][][]byte, error) + ComputeUnQualifiedNodes(validatorInfos state.ShardValidatorsInfoMapHandler) ([][]byte, map[string][][]byte, error) GetBlsKeyOwner(blsKey []byte) (string, error) Clean() IsInterfaceNil() bool diff --git a/epochStart/metachain/legacySystemSCs.go b/epochStart/metachain/legacySystemSCs.go index d01c787f492..0a8bf08cc25 100644 --- a/epochStart/metachain/legacySystemSCs.go +++ b/epochStart/metachain/legacySystemSCs.go @@ -294,7 +294,7 @@ func (s *legacySystemSCProcessor) unStakeNodesWithNotEnoughFunds( validatorsInfoMap state.ShardValidatorsInfoMapHandler, epoch uint32, ) (uint32, error) { - nodesToUnStake, mapOwnersKeys, err := s.stakingDataProvider.ComputeUnQualifiedNodes(validatorsInfoMap.GetValInfoPointerMap()) + nodesToUnStake, mapOwnersKeys, err := s.stakingDataProvider.ComputeUnQualifiedNodes(validatorsInfoMap) if err != nil { return 0, err } diff --git a/epochStart/metachain/stakingDataProvider.go b/epochStart/metachain/stakingDataProvider.go index 2ac6f1c8f68..0d249fd6172 100644 --- a/epochStart/metachain/stakingDataProvider.go +++ b/epochStart/metachain/stakingDataProvider.go @@ -289,7 +289,7 @@ func (sdp *stakingDataProvider) getValidatorInfoFromSC(validatorAddress string) } // ComputeUnQualifiedNodes will compute which nodes are not qualified - do not have enough tokens to be validators -func (sdp *stakingDataProvider) ComputeUnQualifiedNodes(validatorInfos map[uint32][]*state.ValidatorInfo) ([][]byte, map[string][][]byte, error) { +func (sdp *stakingDataProvider) ComputeUnQualifiedNodes(validatorInfos state.ShardValidatorsInfoMapHandler) ([][]byte, map[string][][]byte, error) { sdp.mutStakingData.Lock() defer sdp.mutStakingData.Unlock() @@ -319,12 +319,11 @@ func (sdp *stakingDataProvider) ComputeUnQualifiedNodes(validatorInfos map[uint3 return keysToUnStake, mapOwnersKeys, nil } -func createMapBLSKeyStatus(validatorInfos map[uint32][]*state.ValidatorInfo) map[string]string { +func createMapBLSKeyStatus(validatorInfos state.ShardValidatorsInfoMapHandler) map[string]string { mapBLSKeyStatus := make(map[string]string) - for _, validatorsInfoSlice := range validatorInfos { - for _, validatorInfo := range validatorsInfoSlice { - mapBLSKeyStatus[string(validatorInfo.PublicKey)] = validatorInfo.List - } + for _, validatorInfo := range validatorInfos.GetAllValidatorsInfo() { + mapBLSKeyStatus[string(validatorInfo.GetPublicKey())] = validatorInfo.GetList() + } return mapBLSKeyStatus diff --git a/epochStart/metachain/stakingDataProvider_test.go b/epochStart/metachain/stakingDataProvider_test.go index bb1e371c20e..7c931071f27 100644 --- a/epochStart/metachain/stakingDataProvider_test.go +++ b/epochStart/metachain/stakingDataProvider_test.go @@ -461,7 +461,7 @@ func saveOutputAccounts(t *testing.T, accountsDB state.AccountsAdapter, vmOutput require.Nil(t, err) } -func createStakingDataProviderAndUpdateCache(t *testing.T, validatorsInfo map[uint32][]*state.ValidatorInfo, topUpValue *big.Int) *stakingDataProvider { +func createStakingDataProviderAndUpdateCache(t *testing.T, validatorsInfo state.ShardValidatorsInfoMapHandler, topUpValue *big.Int) *stakingDataProvider { args, _ := createFullArgumentsForSystemSCProcessing(1, createMemUnit()) args.EpochConfig.EnableEpochs.StakingV2EnableEpoch = 0 args.EpochNotifier.CheckEpoch(&testscommon.HeaderHandlerStub{ @@ -472,14 +472,13 @@ func createStakingDataProviderAndUpdateCache(t *testing.T, validatorsInfo map[ui s, _ := NewSystemSCProcessor(args) require.NotNil(t, s) - for _, valsList := range validatorsInfo { - for _, valInfo := range valsList { - stake := big.NewInt(0).Add(big.NewInt(2500), topUpValue) - if valInfo.List != string(common.LeavingList) && valInfo.List != string(common.InactiveList) { - doStake(t, s.systemVM, s.userAccountsDB, valInfo.RewardAddress, stake, valInfo.PublicKey) - } - updateCache(sdp, valInfo.RewardAddress, valInfo.PublicKey, valInfo.List, stake) + for _, valInfo := range validatorsInfo.GetAllValidatorsInfo() { + stake := big.NewInt(0).Add(big.NewInt(2500), topUpValue) + if valInfo.GetList() != string(common.LeavingList) && valInfo.GetList() != string(common.InactiveList) { + doStake(t, s.systemVM, s.userAccountsDB, valInfo.GetRewardAddress(), stake, valInfo.GetPublicKey()) } + updateCache(sdp, valInfo.GetRewardAddress(), valInfo.GetPublicKey(), valInfo.GetList(), stake) + } return sdp @@ -513,12 +512,12 @@ func updateCache(sdp *stakingDataProvider, ownerAddress []byte, blsKey []byte, l sdp.cache[string(ownerAddress)] = owner } -func createValidatorsInfo(nbShards uint32, nbEligible, nbWaiting, nbLeaving, nbInactive map[uint32]uint32) map[uint32][]*state.ValidatorInfo { - validatorsInfo := make(map[uint32][]*state.ValidatorInfo) +func createValidatorsInfo(nbShards uint32, nbEligible, nbWaiting, nbLeaving, nbInactive map[uint32]uint32) state.ShardValidatorsInfoMapHandler { + validatorsInfo := state.NewShardValidatorsInfoMap() shardMap := shardsMap(nbShards) for shardID := range shardMap { - valInfoList := make([]*state.ValidatorInfo, 0) + valInfoList := make([]state.ValidatorInfoHandler, 0) for eligible := uint32(0); eligible < nbEligible[shardID]; eligible++ { vInfo := &state.ValidatorInfo{ PublicKey: []byte(fmt.Sprintf("blsKey%s%d%d", common.EligibleList, shardID, eligible)), @@ -556,7 +555,7 @@ func createValidatorsInfo(nbShards uint32, nbEligible, nbWaiting, nbLeaving, nbI } valInfoList = append(valInfoList, vInfo) } - validatorsInfo[shardID] = valInfoList + _ = validatorsInfo.SetValidatorsInShard(shardID, valInfoList) } return validatorsInfo } diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index e698f165003..e741dfaa617 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -309,7 +309,7 @@ func TestSystemSCProcessor_NobodyToSwapWithStakingV2(t *testing.T) { assert.Equal(t, string(common.JailedList), vInfo.GetList()) } - nodesToUnStake, mapOwnersKeys, err := s.stakingDataProvider.ComputeUnQualifiedNodes(validatorsInfo.GetValInfoPointerMap()) + nodesToUnStake, mapOwnersKeys, err := s.stakingDataProvider.ComputeUnQualifiedNodes(validatorsInfo) assert.Nil(t, err) assert.Equal(t, 0, len(nodesToUnStake)) assert.Equal(t, 0, len(mapOwnersKeys)) diff --git a/epochStart/mock/stakingDataProviderStub.go b/epochStart/mock/stakingDataProviderStub.go index dedd3eb56f3..7b4fd4f0be6 100644 --- a/epochStart/mock/stakingDataProviderStub.go +++ b/epochStart/mock/stakingDataProviderStub.go @@ -14,7 +14,7 @@ type StakingDataProviderStub struct { GetTotalTopUpStakeEligibleNodesCalled func() *big.Int GetNodeStakedTopUpCalled func(blsKey []byte) (*big.Int, error) FillValidatorInfoCalled func(blsKey []byte) error - ComputeUnQualifiedNodesCalled func(validatorInfos map[uint32][]*state.ValidatorInfo) ([][]byte, map[string][][]byte, error) + ComputeUnQualifiedNodesCalled func(validatorInfos state.ShardValidatorsInfoMapHandler) ([][]byte, map[string][][]byte, error) } // FillValidatorInfo - @@ -26,7 +26,7 @@ func (sdps *StakingDataProviderStub) FillValidatorInfo(blsKey []byte) error { } // ComputeUnQualifiedNodes - -func (sdps *StakingDataProviderStub) ComputeUnQualifiedNodes(validatorInfos map[uint32][]*state.ValidatorInfo) ([][]byte, map[string][][]byte, error) { +func (sdps *StakingDataProviderStub) ComputeUnQualifiedNodes(validatorInfos state.ShardValidatorsInfoMapHandler) ([][]byte, map[string][][]byte, error) { if sdps.ComputeUnQualifiedNodesCalled != nil { return sdps.ComputeUnQualifiedNodesCalled(validatorInfos) } @@ -73,7 +73,7 @@ func (sdps *StakingDataProviderStub) Clean() { } // GetBlsKeyOwner - -func (sdps *StakingDataProviderStub) GetBlsKeyOwner(blsKey []byte) (string, error) { +func (sdps *StakingDataProviderStub) GetBlsKeyOwner([]byte) (string, error) { return "", nil } diff --git a/state/interface.go b/state/interface.go index cce1b7ed6ba..597e1851d98 100644 --- a/state/interface.go +++ b/state/interface.go @@ -194,8 +194,6 @@ type ShardValidatorsInfoMapHandler interface { Delete(validator ValidatorInfoHandler) error Replace(old ValidatorInfoHandler, new ValidatorInfoHandler) error SetValidatorsInShard(shardID uint32, validators []ValidatorInfoHandler) error - - GetValInfoPointerMap() map[uint32][]*ValidatorInfo } //ValidatorInfoHandler defines which data shall a validator info hold. diff --git a/state/validatorsInfoMap.go b/state/validatorsInfoMap.go index 01ea7c8fe0b..18c04fb4663 100644 --- a/state/validatorsInfoMap.go +++ b/state/validatorsInfoMap.go @@ -23,33 +23,6 @@ func NewShardValidatorsInfoMap() *shardValidatorsInfoMap { } } -// TODO: Delete these 2 functions once map[uint32][]*ValidatorInfo is completely replaced with new interface - -// CreateShardValidatorsMap creates an instance of shardValidatorsInfoMap which manages a shard validator -// info map internally. -func CreateShardValidatorsMap(input map[uint32][]*ValidatorInfo) *shardValidatorsInfoMap { - ret := &shardValidatorsInfoMap{valInfoMap: make(map[uint32][]ValidatorInfoHandler, len(input))} - - for shardID, valInShard := range input { - for _, val := range valInShard { - ret.valInfoMap[shardID] = append(ret.valInfoMap[shardID], val) - } - } - - return ret -} - -// Replace will replace src with dst map -func Replace(oldMap, newMap map[uint32][]*ValidatorInfo) { - for shardID := range oldMap { - delete(oldMap, shardID) - } - - for shardID, validatorsInShard := range newMap { - oldMap[shardID] = validatorsInShard - } -} - // GetAllValidatorsInfo returns a []ValidatorInfoHandler copy with validators from all shards. func (vi *shardValidatorsInfoMap) GetAllValidatorsInfo() []ValidatorInfoHandler { ret := make([]ValidatorInfoHandler, 0) @@ -198,38 +171,3 @@ func (vi *shardValidatorsInfoMap) Delete(validator ValidatorInfoHandler) error { return nil } - -// TODO: Delete this once map[uint32][]*ValidatorInfo is completely replaced with new interface - -// GetValInfoPointerMap returns a from internally stored data -func (vi *shardValidatorsInfoMap) GetValInfoPointerMap() map[uint32][]*ValidatorInfo { - ret := make(map[uint32][]*ValidatorInfo, 0) - - for shardID, valInShard := range vi.valInfoMap { - for _, val := range valInShard { - ret[shardID] = append(ret[shardID], &ValidatorInfo{ - PublicKey: val.GetPublicKey(), - ShardId: val.GetShardId(), - List: val.GetList(), - Index: val.GetIndex(), - TempRating: val.GetTempRating(), - Rating: val.GetRating(), - RatingModifier: val.GetRatingModifier(), - RewardAddress: val.GetRewardAddress(), - LeaderSuccess: val.GetLeaderSuccess(), - LeaderFailure: val.GetLeaderFailure(), - ValidatorSuccess: val.GetValidatorSuccess(), - ValidatorFailure: val.GetValidatorFailure(), - ValidatorIgnoredSignatures: val.GetValidatorIgnoredSignatures(), - NumSelectedInSuccessBlocks: val.GetNumSelectedInSuccessBlocks(), - AccumulatedFees: val.GetAccumulatedFees(), - TotalLeaderSuccess: val.GetTotalLeaderSuccess(), - TotalLeaderFailure: val.GetTotalLeaderFailure(), - TotalValidatorSuccess: val.GetValidatorSuccess(), - TotalValidatorFailure: val.GetValidatorFailure(), - TotalValidatorIgnoredSignatures: val.GetValidatorIgnoredSignatures(), - }) - } - } - return ret -} diff --git a/state/validatorsInfoMap_test.go b/state/validatorsInfoMap_test.go index 381dbf7f719..8280589bc97 100644 --- a/state/validatorsInfoMap_test.go +++ b/state/validatorsInfoMap_test.go @@ -55,26 +55,6 @@ func TestShardValidatorsInfoMap_OperationsWithNilValidators(t *testing.T) { }) } -func TestCreateShardValidatorsMap(t *testing.T) { - t.Parallel() - - v0 := &ValidatorInfo{ShardId: core.MetachainShardId, PublicKey: []byte("pk0")} - v1 := &ValidatorInfo{ShardId: 1, PublicKey: []byte("pk1")} - v2 := &ValidatorInfo{ShardId: 1, PublicKey: []byte("pk2")} - - input := map[uint32][]*ValidatorInfo{ - core.MetachainShardId: {v0}, - 1: {v1, v2}, - } - expectedValidatorsMap := map[uint32][]ValidatorInfoHandler{ - core.MetachainShardId: {v0}, - 1: {v1, v2}, - } - - vi := CreateShardValidatorsMap(input) - require.Equal(t, expectedValidatorsMap, vi.GetShardValidatorsInfoMap()) -} - func TestShardValidatorsInfoMap_Add_GetShardValidatorsInfoMap_GetAllValidatorsInfo_GetValInfoPointerMap(t *testing.T) { t.Parallel() @@ -104,14 +84,6 @@ func TestShardValidatorsInfoMap_Add_GetShardValidatorsInfoMap_GetAllValidatorsIn core.MetachainShardId: {v3}, } require.Equal(t, validatorsMap, expectedValidatorsMap) - - validatorPointersMap := vi.GetValInfoPointerMap() - expectedValidatorPointersMap := map[uint32][]*ValidatorInfo{ - 0: {v0, v1}, - 1: {v2}, - core.MetachainShardId: {v3}, - } - require.Equal(t, expectedValidatorPointersMap, validatorPointersMap) } func TestShardValidatorsInfoMap_GetValidator(t *testing.T) { @@ -243,10 +215,6 @@ func TestShardValidatorsInfoMap_GettersShouldReturnCopiesOfInternalData(t *testi delete(validatorsMap, 0) validatorsMap[1][0].SetPublicKey([]byte("rnd")) - validatorPointersMap := vi.GetValInfoPointerMap() - delete(validatorPointersMap, 0) - validatorsMap[1][0].SetPublicKey([]byte("rnd")) - validators := vi.GetAllValidatorsInfo() validators = append(validators, &ValidatorInfo{ShardId: 1, PublicKey: []byte("pk3")}) From a5b90f4b8ec376a920c28fb1f3136b7331735bd7 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Tue, 22 Mar 2022 15:04:23 +0200 Subject: [PATCH 2/2] FEAT: Completely remove map[uint32][]*state.ValidatorInfo --- update/genesis/common.go | 20 +++++++------------- update/genesis/export.go | 21 +++++++++------------ update/genesis/export_test.go | 21 +++++++++++---------- 3 files changed, 27 insertions(+), 35 deletions(-) diff --git a/update/genesis/common.go b/update/genesis/common.go index 6de1c53e678..66fa544b958 100644 --- a/update/genesis/common.go +++ b/update/genesis/common.go @@ -6,32 +6,26 @@ import ( "github.com/ElrondNetwork/elrond-go-core/core" "github.com/ElrondNetwork/elrond-go-core/marshal" "github.com/ElrondNetwork/elrond-go/common" - "github.com/ElrondNetwork/elrond-go/sharding" "github.com/ElrondNetwork/elrond-go/state" ) // TODO: create a structure or use this function also in process/peer/process.go func getValidatorDataFromLeaves( leavesChannel chan core.KeyValueHolder, - shardCoordinator sharding.Coordinator, marshalizer marshal.Marshalizer, -) (map[uint32][]*state.ValidatorInfo, error) { - - validators := make(map[uint32][]*state.ValidatorInfo, shardCoordinator.NumberOfShards()+1) - for i := uint32(0); i < shardCoordinator.NumberOfShards(); i++ { - validators[i] = make([]*state.ValidatorInfo, 0) - } - validators[core.MetachainShardId] = make([]*state.ValidatorInfo, 0) - +) (state.ShardValidatorsInfoMapHandler, error) { + validators := state.NewShardValidatorsInfoMap() for pa := range leavesChannel { peerAccount, err := unmarshalPeer(pa.Value(), marshalizer) if err != nil { return nil, err } - currentShardId := peerAccount.GetShardId() validatorInfoData := peerAccountToValidatorInfo(peerAccount) - validators[currentShardId] = append(validators[currentShardId], validatorInfoData) + err = validators.Add(validatorInfoData) + if err != nil { + return nil, err + } } return validators, nil @@ -83,7 +77,7 @@ func getActualList(peerAccount state.PeerAccountHandler) string { return string(common.LeavingList) } -func shouldExportValidator(validator *state.ValidatorInfo, allowedLists []common.PeerType) bool { +func shouldExportValidator(validator state.ValidatorInfoHandler, allowedLists []common.PeerType) bool { validatorList := validator.GetList() for _, list := range allowedLists { diff --git a/update/genesis/export.go b/update/genesis/export.go index 098b6285533..ef115a1ce91 100644 --- a/update/genesis/export.go +++ b/update/genesis/export.go @@ -275,8 +275,7 @@ func (se *stateExport) exportTrie(key string, trie common.Trie) error { } if accType == ValidatorAccount { - var validatorData map[uint32][]*state.ValidatorInfo - validatorData, err = getValidatorDataFromLeaves(leavesChannel, se.shardCoordinator, se.marshalizer) + validatorData, err := getValidatorDataFromLeaves(leavesChannel, se.marshalizer) if err != nil { return err } @@ -391,19 +390,17 @@ func (se *stateExport) exportTx(key string, tx data.TransactionHandler) error { return nil } -func (se *stateExport) exportNodesSetupJson(validators map[uint32][]*state.ValidatorInfo) error { +func (se *stateExport) exportNodesSetupJson(validators state.ShardValidatorsInfoMapHandler) error { acceptedListsForExport := []common.PeerType{common.EligibleList, common.WaitingList, common.JailedList} initialNodes := make([]*sharding.InitialNode, 0) - for _, validatorsInShard := range validators { - for _, validator := range validatorsInShard { - if shouldExportValidator(validator, acceptedListsForExport) { - initialNodes = append(initialNodes, &sharding.InitialNode{ - PubKey: se.validatorPubKeyConverter.Encode(validator.GetPublicKey()), - Address: se.addressPubKeyConverter.Encode(validator.GetRewardAddress()), - InitialRating: validator.GetRating(), - }) - } + for _, validator := range validators.GetAllValidatorsInfo() { + if shouldExportValidator(validator, acceptedListsForExport) { + initialNodes = append(initialNodes, &sharding.InitialNode{ + PubKey: se.validatorPubKeyConverter.Encode(validator.GetPublicKey()), + Address: se.addressPubKeyConverter.Encode(validator.GetRewardAddress()), + InitialRating: validator.GetRating(), + }) } } diff --git a/update/genesis/export_test.go b/update/genesis/export_test.go index 9dc66000ced..da4ffb1b8a6 100644 --- a/update/genesis/export_test.go +++ b/update/genesis/export_test.go @@ -375,16 +375,17 @@ func TestStateExport_ExportNodesSetupJsonShouldExportKeysInAlphabeticalOrder(t * require.False(t, check.IfNil(stateExporter)) - vals := make(map[uint32][]*state.ValidatorInfo) - val50 := &state.ValidatorInfo{ShardId: 5, PublicKey: []byte("aaa"), List: string(common.EligibleList)} - val51 := &state.ValidatorInfo{ShardId: 5, PublicKey: []byte("bbb"), List: string(common.EligibleList)} - val10 := &state.ValidatorInfo{ShardId: 5, PublicKey: []byte("ccc"), List: string(common.EligibleList)} - val11 := &state.ValidatorInfo{ShardId: 5, PublicKey: []byte("ddd"), List: string(common.EligibleList)} - val00 := &state.ValidatorInfo{ShardId: 5, PublicKey: []byte("aaaaaa"), List: string(common.EligibleList)} - val01 := &state.ValidatorInfo{ShardId: 5, PublicKey: []byte("bbbbbb"), List: string(common.EligibleList)} - vals[1] = []*state.ValidatorInfo{val50, val51} - vals[0] = []*state.ValidatorInfo{val00, val01} - vals[2] = []*state.ValidatorInfo{val10, val11} + vals := state.NewShardValidatorsInfoMap() + val50 := &state.ValidatorInfo{ShardId: 0, PublicKey: []byte("aaa"), List: string(common.EligibleList)} + val51 := &state.ValidatorInfo{ShardId: 0, PublicKey: []byte("bbb"), List: string(common.EligibleList)} + val10 := &state.ValidatorInfo{ShardId: 1, PublicKey: []byte("ccc"), List: string(common.EligibleList)} + val11 := &state.ValidatorInfo{ShardId: 1, PublicKey: []byte("ddd"), List: string(common.EligibleList)} + val00 := &state.ValidatorInfo{ShardId: 2, PublicKey: []byte("aaaaaa"), List: string(common.EligibleList)} + val01 := &state.ValidatorInfo{ShardId: 2, PublicKey: []byte("bbbbbb"), List: string(common.EligibleList)} + _ = vals.SetValidatorsInShard(0, []state.ValidatorInfoHandler{val50, val51}) + _ = vals.SetValidatorsInShard(1, []state.ValidatorInfoHandler{val10, val11}) + _ = vals.SetValidatorsInShard(2, []state.ValidatorInfoHandler{val00, val01}) + err = stateExporter.exportNodesSetupJson(vals) require.Nil(t, err)