Skip to content

Commit

Permalink
Merge pull request #5334 from multiversx/feat/state-refactor
Browse files Browse the repository at this point in the history
Feat/state refactor
  • Loading branch information
BeniaminDrasovean authored Jul 4, 2023
2 parents 61159b2 + 81d8e8a commit a8ba8c6
Show file tree
Hide file tree
Showing 104 changed files with 2,274 additions and 2,133 deletions.
4 changes: 2 additions & 2 deletions api/groups/validatorGroup.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ import (
"github.com/multiversx/mx-chain-core-go/core/check"
"github.com/multiversx/mx-chain-go/api/errors"
"github.com/multiversx/mx-chain-go/api/shared"
"github.com/multiversx/mx-chain-go/state"
"github.com/multiversx/mx-chain-go/state/accounts"
)

const statisticsPath = "/statistics"

// validatorFacadeHandler defines the methods to be implemented by a facade for validator requests
type validatorFacadeHandler interface {
ValidatorStatisticsApi() (map[string]*state.ValidatorApiResponse, error)
ValidatorStatisticsApi() (map[string]*accounts.ValidatorApiResponse, error)
IsInterfaceNil() bool
}

Expand Down
23 changes: 12 additions & 11 deletions api/groups/validatorGroup_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
"github.com/multiversx/mx-chain-go/api/mock"
"github.com/multiversx/mx-chain-go/api/shared"
"github.com/multiversx/mx-chain-go/config"
"github.com/multiversx/mx-chain-go/state"
"github.com/multiversx/mx-chain-go/state/accounts"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
Expand All @@ -33,9 +33,10 @@ func TestNewValidatorGroup(t *testing.T) {
})
}

// ValidatorStatisticsResponse is the response for the validator statistics endpoint.
type ValidatorStatisticsResponse struct {
Result map[string]*state.ValidatorApiResponse `json:"statistics"`
Error string `json:"error"`
Result map[string]*accounts.ValidatorApiResponse `json:"statistics"`
Error string `json:"error"`
}

func TestValidatorStatistics_ErrorWhenFacadeFails(t *testing.T) {
Expand All @@ -44,7 +45,7 @@ func TestValidatorStatistics_ErrorWhenFacadeFails(t *testing.T) {
errStr := "error in facade"

facade := mock.FacadeStub{
ValidatorStatisticsHandler: func() (map[string]*state.ValidatorApiResponse, error) {
ValidatorStatisticsHandler: func() (map[string]*accounts.ValidatorApiResponse, error) {
return nil, errors.New(errStr)
},
}
Expand All @@ -69,16 +70,16 @@ func TestValidatorStatistics_ErrorWhenFacadeFails(t *testing.T) {
func TestValidatorStatistics_ReturnsSuccessfully(t *testing.T) {
t.Parallel()

mapToReturn := make(map[string]*state.ValidatorApiResponse)
mapToReturn["test"] = &state.ValidatorApiResponse{
mapToReturn := make(map[string]*accounts.ValidatorApiResponse)
mapToReturn["test"] = &accounts.ValidatorApiResponse{
NumLeaderSuccess: 5,
NumLeaderFailure: 2,
NumValidatorSuccess: 7,
NumValidatorFailure: 3,
}

facade := mock.FacadeStub{
ValidatorStatisticsHandler: func() (map[string]*state.ValidatorApiResponse, error) {
ValidatorStatisticsHandler: func() (map[string]*accounts.ValidatorApiResponse, error) {
return mapToReturn, nil
},
}
Expand Down Expand Up @@ -130,15 +131,15 @@ func TestValidatorGroup_UpdateFacade(t *testing.T) {
t.Run("should work", func(t *testing.T) {
t.Parallel()

mapToReturn := make(map[string]*state.ValidatorApiResponse)
mapToReturn["test"] = &state.ValidatorApiResponse{
mapToReturn := make(map[string]*accounts.ValidatorApiResponse)
mapToReturn["test"] = &accounts.ValidatorApiResponse{
NumLeaderSuccess: 5,
NumLeaderFailure: 2,
NumValidatorSuccess: 7,
NumValidatorFailure: 3,
}
facade := mock.FacadeStub{
ValidatorStatisticsHandler: func() (map[string]*state.ValidatorApiResponse, error) {
ValidatorStatisticsHandler: func() (map[string]*accounts.ValidatorApiResponse, error) {
return mapToReturn, nil
},
}
Expand All @@ -162,7 +163,7 @@ func TestValidatorGroup_UpdateFacade(t *testing.T) {

expectedErr := errors.New("expected error")
newFacade := mock.FacadeStub{
ValidatorStatisticsHandler: func() (map[string]*state.ValidatorApiResponse, error) {
ValidatorStatisticsHandler: func() (map[string]*accounts.ValidatorApiResponse, error) {
return nil, expectedErr
},
}
Expand Down
5 changes: 3 additions & 2 deletions api/mock/facadeStub.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"github.com/multiversx/mx-chain-go/process"
txSimData "github.com/multiversx/mx-chain-go/process/transactionEvaluator/data"
"github.com/multiversx/mx-chain-go/state"
"github.com/multiversx/mx-chain-go/state/accounts"
)

// FacadeStub is the mock implementation of a node router handler
Expand All @@ -35,7 +36,7 @@ type FacadeStub struct {
SendBulkTransactionsHandler func(txs []*transaction.Transaction) (uint64, error)
ExecuteSCQueryHandler func(query *process.SCQuery) (*vm.VMOutputApi, error)
StatusMetricsHandler func() external.StatusMetricsHandler
ValidatorStatisticsHandler func() (map[string]*state.ValidatorApiResponse, error)
ValidatorStatisticsHandler func() (map[string]*accounts.ValidatorApiResponse, error)
ComputeTransactionGasLimitHandler func(tx *transaction.Transaction) (*transaction.CostResponse, error)
NodeConfigCalled func() map[string]interface{}
GetQueryHandlerCalled func(name string) (debug.QueryHandler, error)
Expand Down Expand Up @@ -321,7 +322,7 @@ func (f *FacadeStub) ValidateTransactionForSimulation(tx *transaction.Transactio
}

// ValidatorStatisticsApi is the mock implementation of a handler's ValidatorStatisticsApi method
func (f *FacadeStub) ValidatorStatisticsApi() (map[string]*state.ValidatorApiResponse, error) {
func (f *FacadeStub) ValidatorStatisticsApi() (map[string]*accounts.ValidatorApiResponse, error) {
return f.ValidatorStatisticsHandler()
}

Expand Down
3 changes: 2 additions & 1 deletion api/shared/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"github.com/multiversx/mx-chain-go/process"
txSimData "github.com/multiversx/mx-chain-go/process/transactionEvaluator/data"
"github.com/multiversx/mx-chain-go/state"
"github.com/multiversx/mx-chain-go/state/accounts"
)

// HttpServerCloser defines the basic actions of starting and closing that a web server should be able to do
Expand Down Expand Up @@ -113,7 +114,7 @@ type FacadeHandler interface {
GetTransaction(hash string, withResults bool) (*transaction.ApiTransactionResult, error)
ComputeTransactionGasLimit(tx *transaction.Transaction) (*transaction.CostResponse, error)
EncodeAddressPubkey(pk []byte) (string, error)
ValidatorStatisticsApi() (map[string]*state.ValidatorApiResponse, error)
ValidatorStatisticsApi() (map[string]*accounts.ValidatorApiResponse, error)
ExecuteSCQuery(*process.SCQuery) (*vm.VMOutputApi, error)
DecodeAddressPubkey(pk string) ([]byte, error)
RestApiInterface() string
Expand Down
68 changes: 41 additions & 27 deletions epochStart/metachain/baseRewards_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,14 @@ import (
"github.com/multiversx/mx-chain-go/epochStart/mock"
"github.com/multiversx/mx-chain-go/process"
"github.com/multiversx/mx-chain-go/sharding"
"github.com/multiversx/mx-chain-go/state"
"github.com/multiversx/mx-chain-go/state/factory"
"github.com/multiversx/mx-chain-go/testscommon"
dataRetrieverMock "github.com/multiversx/mx-chain-go/testscommon/dataRetriever"
"github.com/multiversx/mx-chain-go/testscommon/enableEpochsHandlerMock"
"github.com/multiversx/mx-chain-go/testscommon/hashingMocks"
"github.com/multiversx/mx-chain-go/testscommon/marshallerMock"
"github.com/multiversx/mx-chain-go/testscommon/shardingMocks"
stateMock "github.com/multiversx/mx-chain-go/testscommon/state"
"github.com/multiversx/mx-chain-go/testscommon/storage"
trieMock "github.com/multiversx/mx-chain-go/testscommon/trie"
"github.com/multiversx/mx-chain-go/trie"
vmcommon "github.com/multiversx/mx-chain-vm-common-go"
"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -818,41 +815,58 @@ func TestBaseRewardsCreator_RemoveBlockDataFromPools(t *testing.T) {
func TestBaseRewardsCreator_isSystemDelegationSC(t *testing.T) {
t.Parallel()

nonExistentAccountAddress := []byte("address")
peerAccountAddress := []byte("addressPeer")
userAccountAddress := []byte("addressUser")

args := getBaseRewardsArguments()
args.UserAccountsDB = &stateMock.AccountsStub{
GetExistingAccountCalled: func(addressContainer []byte) (vmcommon.AccountHandler, error) {
if bytes.Equal(addressContainer, nonExistentAccountAddress) {
return nil, fmt.Errorf("account does not exist")
}

if bytes.Equal(addressContainer, peerAccountAddress) {
peerAccount := &stateMock.PeerAccountHandlerMock{
AddressBytesCalled: func() []byte {
return peerAccountAddress
},
}

return peerAccount, nil
}

if bytes.Equal(addressContainer, userAccountAddress) {
userAccount := &stateMock.UserAccountStub{
RetrieveValueCalled: func(key []byte) ([]byte, uint32, error) {
if bytes.Equal(key, []byte(core.DelegationSystemSCKey)) {
return []byte("delegation"), 0, nil
}
return nil, 0, fmt.Errorf("not found")
},
}

return userAccount, nil
}

return &stateMock.UserAccountStub{}, nil
},
}
rwd, err := NewBaseRewardsCreator(args)
require.Nil(t, err)
require.NotNil(t, rwd)

// not existing account
isDelegationSCAddress := rwd.isSystemDelegationSC([]byte("address"))
isDelegationSCAddress := rwd.isSystemDelegationSC(nonExistentAccountAddress)
require.False(t, isDelegationSCAddress)

// peer account
peerAccount, err := state.NewPeerAccount([]byte("addressPeer"))
require.Nil(t, err)
err = rwd.userAccountsDB.SaveAccount(peerAccount)
require.Nil(t, err)
isDelegationSCAddress = rwd.isSystemDelegationSC(peerAccount.AddressBytes())
isDelegationSCAddress = rwd.isSystemDelegationSC(peerAccountAddress)
require.False(t, isDelegationSCAddress)

argsAccCreation := state.ArgsAccountCreation{
Hasher: &hashingMocks.HasherMock{},
Marshaller: &marshallerMock.MarshalizerMock{},
EnableEpochsHandler: &enableEpochsHandlerMock.EnableEpochsHandlerStub{},
}
// existing user account
userAccount, err := state.NewUserAccount([]byte("userAddress"), argsAccCreation)
require.Nil(t, err)

userAccount.SetDataTrie(&trieMock.TrieStub{
GetCalled: func(key []byte) ([]byte, uint32, error) {
if bytes.Equal(key, []byte(core.DelegationSystemSCKey)) {
return []byte("delegation"), 0, nil
}
return nil, 0, fmt.Errorf("not found")
},
})

isDelegationSCAddress = rwd.isSystemDelegationSC(userAccountAddress)
require.True(t, isDelegationSCAddress)
}

func TestBaseRewardsCreator_isSystemDelegationSCTrue(t *testing.T) {
Expand Down Expand Up @@ -1148,7 +1162,7 @@ func getBaseRewardsArguments() BaseRewardsCreatorArgs {
storageManagerArgs.Hasher = hasher

trieFactoryManager, _ := trie.CreateTrieStorageManager(storageManagerArgs, storage.GetStorageManagerOptions())
argsAccCreator := state.ArgsAccountCreation{
argsAccCreator := factory.ArgsAccountCreator{
Hasher: hasher,
Marshaller: marshalizer,
EnableEpochsHandler: &enableEpochsHandlerMock.EnableEpochsHandlerStub{},
Expand Down
15 changes: 3 additions & 12 deletions epochStart/metachain/systemSCs.go
Original file line number Diff line number Diff line change
Expand Up @@ -776,7 +776,8 @@ func (s *systemSCProcessor) stakingToValidatorStatistics(

blsPubKey := activeStorageUpdate.Offset
log.Debug("staking validator key who switches with the jailed one", "blsKey", blsPubKey)
account, err := s.getPeerAccount(blsPubKey)

account, isNew, err := state.GetPeerAccountAndReturnIfNew(s.peerAccountsDB, blsPubKey)
if err != nil {
return nil, err
}
Expand All @@ -788,12 +789,7 @@ func (s *systemSCProcessor) stakingToValidatorStatistics(
}
}

if !bytes.Equal(account.GetBLSPublicKey(), blsPubKey) {
err = account.SetBLSPublicKey(blsPubKey)
if err != nil {
return nil, err
}
} else {
if !isNew {
// old jailed validator getting switched back after unJail with stake - must remove first from exported map
deleteNewValidatorIfExistsFromMap(validatorInfos, blsPubKey, account.GetShardId())
}
Expand Down Expand Up @@ -1329,11 +1325,6 @@ func (s *systemSCProcessor) addNewlyStakedNodesToValidatorTrie(
return err
}

err = peerAcc.SetBLSPublicKey(blsKey)
if err != nil {
return err
}

peerAcc.SetListAndIndex(peerAcc.GetShardId(), string(common.NewList), uint32(nonce))
peerAcc.SetTempRating(s.startRating)
peerAcc.SetUnStakedEpoch(common.DefaultUnstakedEpoch)
Expand Down
59 changes: 55 additions & 4 deletions epochStart/metachain/systemSCs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -918,7 +918,7 @@ func createFullArgumentsForSystemSCProcessing(enableEpochsConfig config.EnableEp
storageManagerArgs.CheckpointsStorer = trieStorer

trieFactoryManager, _ := trie.CreateTrieStorageManager(storageManagerArgs, storageMock.GetStorageManagerOptions())
argsAccCreator := state.ArgsAccountCreation{
argsAccCreator := factory.ArgsAccountCreator{
Hasher: hasher,
Marshaller: marshalizer,
EnableEpochsHandler: &enableEpochsHandlerMock.EnableEpochsHandlerStub{},
Expand Down Expand Up @@ -1302,7 +1302,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractMaxNodesStakedFromQueue(t *

peerAcc, err := s.getPeerAccount([]byte("waitingPubKey"))
assert.Nil(t, err)
assert.True(t, bytes.Equal(peerAcc.GetBLSPublicKey(), []byte("waitingPubKey")))
assert.True(t, bytes.Equal(peerAcc.AddressBytes(), []byte("waitingPubKey")))
assert.Equal(t, peerAcc.GetList(), string(common.NewList))
numRegistered := getTotalNumberOfRegisteredNodes(t, s)
assert.Equal(t, 1, numRegistered)
Expand Down Expand Up @@ -1355,7 +1355,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractMaxNodesStakedFromQueueOwne

peerAcc, err := s.getPeerAccount([]byte("waitingPubKey"))
assert.Nil(t, err)
assert.True(t, bytes.Equal(peerAcc.GetBLSPublicKey(), []byte("waitingPubKey")))
assert.True(t, bytes.Equal(peerAcc.AddressBytes(), []byte("waitingPubKey")))
assert.Equal(t, peerAcc.GetList(), string(common.NewList))
}

Expand Down Expand Up @@ -1450,7 +1450,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractUnStakeOneNodeStakeOthers(t

peerAcc, err := s.getPeerAccount([]byte("waitingPubKey"))
assert.Nil(t, err)
assert.True(t, bytes.Equal(peerAcc.GetBLSPublicKey(), []byte("waitingPubKey")))
assert.True(t, bytes.Equal(peerAcc.AddressBytes(), []byte("waitingPubKey")))
assert.Equal(t, peerAcc.GetList(), string(common.NewList))

peerAcc, _ = s.getPeerAccount([]byte("stakedPubKey1"))
Expand Down Expand Up @@ -1950,3 +1950,54 @@ func TestSystemSCProcessor_ProcessSystemSmartContractJailAndUnStake(t *testing.T
assert.Equal(t, peerAcc.GetList(), string(common.LeavingList))
}
}

func TestSystemSCProcessor_ProcessSystemSmartContractSwapJailedWithWaiting(t *testing.T) {
t.Parallel()

args, _ := createFullArgumentsForSystemSCProcessing(config.EnableEpochs{}, createMemUnit())
args.ChanceComputer = &mock.ChanceComputerStub{
GetChanceCalled: func(rating uint32) uint32 {
if rating == 0 {
return 10
}
return rating
},
}
s, _ := NewSystemSCProcessor(args)

prepareStakingContractWithData(
args.UserAccountsDB,
[]byte("jailedPubKey0"),
[]byte("waitingPubKey"),
args.Marshalizer,
[]byte("rewardAddress"),
[]byte("rewardAddress"),
)
jailedAcc, _ := args.PeerAccountsDB.LoadAccount([]byte("jailedPubKey0"))
_ = args.PeerAccountsDB.SaveAccount(jailedAcc)

validatorInfos := make(map[uint32][]*state.ValidatorInfo)
vInfo := &state.ValidatorInfo{
PublicKey: []byte("jailedPubKey0"),
ShardId: 0,
List: string(common.JailedList),
TempRating: 1,
RewardAddress: []byte("address"),
AccumulatedFees: big.NewInt(0),
}
validatorInfos[0] = append(validatorInfos[0], vInfo)

vInfo1 := &state.ValidatorInfo{
PublicKey: []byte("waitingPubKey"),
ShardId: 0,
List: string(common.WaitingList),
}
validatorInfos[0] = append(validatorInfos[0], vInfo1)

err := s.ProcessSystemSmartContract(validatorInfos, 0, 0)
assert.Nil(t, err)

assert.Equal(t, 2, len(validatorInfos[0]))
newValidatorInfo := validatorInfos[0][0]
assert.Equal(t, newValidatorInfo.List, string(common.NewList))
}
Loading

0 comments on commit a8ba8c6

Please sign in to comment.